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
ANIUtils_ANIStringToStdString(ani_env * env,ani_string ani_str)26 std::string ANIUtils_ANIStringToStdString(ani_env *env, ani_string ani_str)
27 {
28 ani_size strSize;
29 env->String_GetUTF8Size(ani_str, &strSize);
30
31 std::vector<char> buffer(strSize + 1);
32 char* utf8Buffer = buffer.data();
33
34 ani_size bytesWritten = 0;
35 env->String_GetUTF8(ani_str, utf8Buffer, strSize + 1, &bytesWritten);
36
37 utf8Buffer[bytesWritten] = '\0';
38 std::string content = std::string(utf8Buffer);
39 return content;
40 }
GetToastMessage(ani_env * env,ani_object options,std::string & messageString)41 bool GetToastMessage(ani_env *env, ani_object options, std::string& messageString)
42 {
43 static const char *className = "L@ohos/prompt/prompt/ShowToastOptions;";
44 ani_class cls;
45 if (ANI_OK != env->FindClass(className, &cls)) {
46 return false;
47 }
48
49 ani_ref message_ref;
50 if (ANI_OK != env->Object_GetPropertyByName_Ref(options, "message", &message_ref)) {
51 return false;
52 }
53
54 auto message_str = ANIUtils_ANIStringToStdString(env, static_cast<ani_string>(message_ref));
55 messageString = message_str;
56 return true;
57 }
GetToastDuration(ani_env * env,ani_object options,int32_t & durationInt)58 bool GetToastDuration(ani_env *env, ani_object options, int32_t& durationInt)
59 {
60 static const char *className = "L@ohos/prompt/prompt/ShowToastOptions;";
61 ani_class cls;
62 if (ANI_OK != env->FindClass(className, &cls)) {
63 std::cerr << "Not found '" << className << "'" << std::endl;
64 return false;
65 }
66 ani_ref duration_ref;
67 if (ANI_OK != env->Object_GetPropertyByName_Ref(options, "duration", &duration_ref)) {
68 return false;
69 }
70 ani_boolean isUndefined;
71 if (ANI_OK != env->Reference_IsUndefined(duration_ref, &isUndefined)) {
72 return false;
73 }
74 if (isUndefined) {
75 return false;
76 }
77 ani_double duration;
78 if (ANI_OK != env->Object_CallMethodByName_Double(
79 static_cast<ani_object>(duration_ref), "doubleValue", nullptr, &duration)) {
80 return false;
81 }
82 durationInt = static_cast<int32_t>(duration);
83 return true;
84 }
GetToastBottom(ani_env * env,ani_object options,std::string & bottomString)85 bool GetToastBottom(ani_env *env, ani_object options, std::string& bottomString)
86 {
87 static const char *className = "L@ohos/prompt/prompt/ShowToastOptions;";
88 ani_class cls;
89 if (ANI_OK != env->FindClass(className, &cls)) {
90 return false;
91 }
92 ani_ref bottom_ref;
93 if (ANI_OK != env->Object_GetPropertyByName_Ref(options, "bottom", &bottom_ref)) {
94 return false;
95 }
96 ani_boolean isUndefined;
97 if (ANI_OK != env->Reference_IsUndefined(bottom_ref, &isUndefined)) {
98 return false;
99 }
100 if (isUndefined) {
101 return false;
102 }
103 ani_class stringClass;
104 env->FindClass("Lstd/core/String;", &stringClass);
105
106 ani_class numberClass;
107 env->FindClass("Lstd/core/Numeric;", &numberClass);
108
109 ani_boolean isString;
110 env->Object_InstanceOf(static_cast<ani_object>(bottom_ref), stringClass, &isString);
111 if (isString) {
112 auto stringContent = ANIUtils_ANIStringToStdString(env, static_cast<ani_string>(bottom_ref));
113 bottomString = stringContent;
114 return true;
115 }
116 ani_boolean isNumber;
117 env->Object_InstanceOf(static_cast<ani_object>(bottom_ref), numberClass, &isNumber);
118 if (isNumber) {
119 ani_double duration;
120 if (ANI_OK !=env->Object_CallMethodByName_Double(
121 static_cast<ani_object>(bottom_ref), "doubleValue", nullptr, &duration)) {
122 return false;
123 }
124 double botm = static_cast<double>(duration);
125 bottomString = std::to_string(botm);
126 }
127 return true;
128 }
showToast(ani_env * env,ani_object options)129 static void showToast([[maybe_unused]] ani_env* env, ani_object options)
130 {
131 std::string messageInfo;
132 std::string bottomInfo;
133 int32_t durationInfo = 0;
134 ani_boolean isUndefined;
135 env->Reference_IsUndefined(options, &isUndefined);
136 if (isUndefined) {
137 return;
138 }
139 GetToastMessage(env, options, messageInfo);
140 std::cout << "GetToastMessage :" << messageInfo.c_str() << std::endl;
141 GetToastDuration(env, options, durationInfo);
142 std::cout << "GetToastDuration :" << durationInfo << std::endl;
143 GetToastBottom(env, options, bottomInfo);
144 std::cout << "GetToastBottom :" << bottomInfo.c_str() << std::endl;
145 auto toastInfo = OHOS::Ace::NG::ToastInfo { .message = messageInfo,
146 .duration = durationInfo,
147 .bottom = bottomInfo,
148 .showMode = OHOS::Ace::NG::ToastShowMode::DEFAULT,
149 .alignment = -1,
150 .offset = std::nullopt };
151 auto delegate = OHOS::Ace::EngineHelper::GetCurrentDelegateSafely();
152 if (delegate) {
153 delegate->ShowToast(toastInfo, nullptr);
154 }
155 }
ANI_Constructor(ani_vm * vm,uint32_t * result)156 ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result)
157 {
158 ani_env *env;
159 if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) {
160 return ANI_ERROR;
161 }
162
163 ani_namespace ns;
164 if (ANI_OK != env->FindNamespace("L@ohos/prompt/prompt;", &ns)) {
165 return ANI_ERROR;
166 }
167 std::array methods = {
168 ani_native_function {"showToast", nullptr, reinterpret_cast<void *>(showToast)},
169 };
170 if (ANI_OK != env->Namespace_BindNativeFunctions(ns, methods.data(), methods.size())) {
171 return ANI_ERROR;
172 }
173
174 *result = ANI_VERSION_1;
175 return ANI_OK;
176 }
177