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 #include "sts_action_button.h"
16
17 #include "sts_common.h"
18 #include "sts_convert_other.h"
19 #include "ani_common_want.h"
20 #include "ans_log_wrapper.h"
21 #include "sts_user_input.h"
22
23
24 namespace OHOS {
25 namespace NotificationSts {
GetStsActionButtonByOther(StsActionButton & actionButton)26 void GetStsActionButtonByOther(StsActionButton &actionButton)
27 {
28 ANS_LOGD("GetStsActionButtonByOther call");
29 actionButton.icon = nullptr;
30 actionButton.semanticActionButton = SemanticActionButton::NONE_ACTION_BUTTON;
31 actionButton.autoCreatedReplies = true;
32 actionButton.mimeTypeOnlyInputs = {};
33 actionButton.isContextual = false;
34 ANS_LOGD("GetStsActionButtonByOther end");
35 }
GetStsActionButtonByWantAgent(ani_env * env,ani_object param,StsActionButton & actionButton)36 ani_status GetStsActionButtonByWantAgent(ani_env *env, ani_object param,
37 StsActionButton &actionButton)
38 {
39 ANS_LOGD("GetStsActionButtonByWantAgent call");
40 if (env == nullptr || param == nullptr) {
41 ANS_LOGE("GetStsActionButtonByWantAgent fail, has nullptr");
42 return ANI_ERROR;
43 }
44 ani_boolean isUndefind = ANI_TRUE;
45 ani_ref wantAgentRef;
46 if (ANI_OK != GetPropertyRef(env, param, "wantAgent", isUndefind, wantAgentRef) || isUndefind == ANI_TRUE) {
47 ANS_LOGE("GetStsActionButtonByWantAgent: GetPropertyRef wantAgent failed");
48 return ANI_INVALID_ARGS;
49 }
50 std::shared_ptr<WantAgent> wantAgent = UnwrapWantAgent(env, static_cast<ani_object>(wantAgentRef));
51 if (wantAgent == nullptr) {
52 ANS_LOGE("GetStsActionButtonByWantAgent: wantAgent is nullptr");
53 return ANI_INVALID_ARGS;
54 }
55 actionButton.wantAgent = wantAgent;
56 ANS_LOGD("GetStsActionButtonByWantAgent end");
57 return ANI_OK;
58 }
59
GetStsActionButtonByWantParams(ani_env * env,ani_object param,StsActionButton & actionButton)60 ani_status GetStsActionButtonByWantParams(ani_env *env, ani_object param,
61 StsActionButton &actionButton)
62 {
63 ANS_LOGD("GetStsActionButtonByWantParams call");
64 if (env == nullptr || param == nullptr) {
65 ANS_LOGE("GetStsActionButtonByWantParams fail, has nullptr");
66 return ANI_ERROR;
67 }
68 ani_boolean isUndefind = ANI_TRUE;
69 WantParams wantParams = {};
70 ani_ref extrasRef;
71 if (ANI_OK == GetPropertyRef(env, param, "extras", isUndefind, extrasRef) && isUndefind == ANI_FALSE) {
72 UnwrapWantParams(env, extrasRef, wantParams);
73 } else {
74 ANS_LOGE("GetStsActionButtonByWantParams: GetPropertyRef extras failed");
75 return ANI_INVALID_ARGS;
76 }
77 std::shared_ptr<WantParams> extras = std::make_shared<WantParams>(wantParams);
78 actionButton.extras = extras;
79 ANS_LOGD("GetStsActionButtonByWantParams end");
80 return ANI_OK;
81 }
GetStsActionButtonByUserInput(ani_env * env,ani_object param,StsActionButton & actionButton)82 ani_status GetStsActionButtonByUserInput(ani_env *env, ani_object param,
83 StsActionButton &actionButton)
84 {
85 ANS_LOGD("GetStsActionButtonByUserInput call");
86 if (env == nullptr || param == nullptr) {
87 ANS_LOGE("GetStsActionButtonByUserInput fail, has nullptr");
88 return ANI_ERROR;
89 }
90 ani_boolean isUndefind = ANI_TRUE;
91 std::shared_ptr<Notification::NotificationUserInput> userInput = nullptr;
92 ani_ref userInputRef;
93 if (ANI_OK == GetPropertyRef(env, param, "userInput", isUndefind, userInputRef) && isUndefind == ANI_FALSE) {
94 UnwrapNotificationUserInput(env, static_cast<ani_object>(userInputRef), userInput);
95 } else {
96 ANS_LOGD("GetStsActionButtonByUserInput : GetPropertyRef userInput failed");
97 }
98 if (userInput == nullptr) {
99 ANS_LOGD("GetStsActionButtonByUserInput : userInput is nullptr");
100 userInput = {};
101 }
102 actionButton.userInput = userInput;
103 ANS_LOGD("GetStsActionButtonByUserInput end");
104 return ANI_OK;
105 }
106
UnwrapNotificationActionButton(ani_env * env,ani_object param,StsActionButton & actionButton)107 ani_status UnwrapNotificationActionButton(ani_env *env, ani_object param,
108 StsActionButton &actionButton)
109 {
110 ANS_LOGD("UnwrapNotificationActionButton call");
111 if (env == nullptr || param == nullptr) {
112 ANS_LOGE("UnwrapNotificationActionButton fail, has nullptr");
113 return ANI_ERROR;
114 }
115 ani_status status = ANI_ERROR;
116 ani_boolean isUndefind = ANI_TRUE;
117 std::string title;
118 if ((status = GetPropertyString(env, param, "title", isUndefind, title)) != ANI_OK || isUndefind == ANI_TRUE) {
119 ANS_LOGE("UnwrapNotificationActionButton : Get title failed");
120 return ANI_INVALID_ARGS;
121 }
122 actionButton.title = title;
123 if (ANI_OK != GetStsActionButtonByWantAgent(env, param, actionButton)) {
124 ANS_LOGE("UnwrapNotificationActionButton : GetStsActionButtonByWantAgent failed");
125 return ANI_INVALID_ARGS;
126 }
127 if (ANI_OK != GetStsActionButtonByWantParams(env, param, actionButton)) {
128 ANS_LOGE("UnwrapNotificationActionButton : GetStsActionButtonByWantParams failed");
129 return ANI_INVALID_ARGS;
130 }
131 GetStsActionButtonByOther(actionButton);
132 ANS_LOGD("UnwrapNotificationActionButton end");
133 return status;
134 }
135
SetNotificationActionButtonByRequiredParameter(ani_env * env,ani_class iconButtonCls,ani_object & iconButtonObject,const std::shared_ptr<NotificationActionButton> & actionButton)136 bool SetNotificationActionButtonByRequiredParameter(
137 ani_env *env,
138 ani_class iconButtonCls,
139 ani_object &iconButtonObject,
140 const std::shared_ptr<NotificationActionButton> &actionButton)
141 {
142 ANS_LOGD("SetActionButtonByRequiredParameter call");
143 if (env == nullptr || iconButtonCls == nullptr || iconButtonObject == nullptr || actionButton == nullptr) {
144 ANS_LOGE("SetActionButtonByRequiredParameter fail, has nullptr");
145 return ANI_ERROR;
146 }
147 ani_string stringValue;
148 // title: string;
149 if (ANI_OK != GetAniStringByString(env, actionButton->GetTitle(), stringValue)) {
150 ANS_LOGE("SetActionButtonByRequiredParameter: Get title failed");
151 return false;
152 }
153 if (!CallSetter(env, iconButtonCls, iconButtonObject, "title", stringValue)) {
154 ANS_LOGE("SetActionButtonByRequiredParameter: Set title failed");
155 return false;
156 }
157 // wantAgent: WantAgent;
158 std::shared_ptr<AbilityRuntime::WantAgent::WantAgent> agent = actionButton->GetWantAgent();
159 if (agent == nullptr) {
160 ANS_LOGE("SetActionButtonByRequiredParameter:agent is null");
161 return false;
162 } else {
163 ani_object wantAgent = AppExecFwk::WrapWantAgent(env, agent.get());
164 if (wantAgent == nullptr) {
165 ANS_LOGE("SetActionButtonByRequiredParameter: wantAgent is nullptr");
166 return false;
167 }
168 if (!CallSetter(env, iconButtonCls, iconButtonObject, "wantAgent", wantAgent)) {
169 ANS_LOGE("SetActionButtonByRequiredParameter: Set wantAgent failed");
170 return false;
171 }
172 }
173 ANS_LOGD("SetActionButtonByRequiredParameter end");
174 return true;
175 }
176
SetNotificationActionButtonByOptionalParameter(ani_env * env,ani_class iconButtonCls,ani_object & iconButtonObject,const std::shared_ptr<NotificationActionButton> & actionButton)177 void SetNotificationActionButtonByOptionalParameter(
178 ani_env *env,
179 ani_class iconButtonCls,
180 ani_object &iconButtonObject,
181 const std::shared_ptr<NotificationActionButton> &actionButton)
182 {
183 ANS_LOGD("SetActionButtonByOptionalParameter call");
184 if (env == nullptr || iconButtonCls == nullptr || iconButtonObject == nullptr || actionButton == nullptr) {
185 ANS_LOGE("SetActionButtonByOptionalParameter fail, has nullptr");
186 return;
187 }
188 // extras?: Record<string, Object>
189 ani_ref extras = WrapWantParams(env, *(actionButton->GetAdditionalData().get()));
190 if (!CallSetter(env, iconButtonCls, iconButtonObject, "extras", extras)) {
191 ANS_LOGD("SetActionButtonByOptionalParameter : Set extras failed");
192 }
193 // userInput?: NotificationUserInput
194 ani_object userInputObject = WarpUserInput(env, actionButton->GetUserInput());
195 if (!CallSetter(env, iconButtonCls, iconButtonObject, "userInput", userInputObject)) {
196 ANS_LOGD("SetActionButtonByOptionalParameter : Set userInput failed");
197 }
198 ANS_LOGD("SetActionButtonByOptionalParameter end");
199 }
200
WrapNotificationActionButton(ani_env * env,const std::shared_ptr<NotificationActionButton> & actionButton)201 ani_object WrapNotificationActionButton(ani_env* env,
202 const std::shared_ptr<NotificationActionButton> &actionButton)
203 {
204 ANS_LOGD("WrapNotificationActionButton call");
205 if (env == nullptr || actionButton == nullptr) {
206 ANS_LOGE("WrapNotificationActionButton failed, has nullptr");
207 return nullptr;
208 }
209 ani_object iconButtonObject = nullptr;
210 ani_class iconButtonCls = nullptr;
211 if (!CreateClassObjByClassName(env,
212 "Lnotification/notificationActionButton/NotificationActionButtonInner;", iconButtonCls, iconButtonObject)) {
213 ANS_LOGE("WrapNotificationActionButton : CreateClassObjByClassName failed");
214 return nullptr;
215 }
216 if (!SetNotificationActionButtonByRequiredParameter(env, iconButtonCls, iconButtonObject, actionButton)) {
217 ANS_LOGE("WrapNotificationActionButton : SetRequiredParameter failed");
218 return nullptr;
219 }
220 SetNotificationActionButtonByOptionalParameter(env, iconButtonCls, iconButtonObject, actionButton);
221 ANS_LOGE("WrapNotificationActionButton end");
222 return iconButtonObject;
223 }
224
GetNotificationActionButtonArray(ani_env * env,ani_object param,const char * name,std::vector<std::shared_ptr<NotificationActionButton>> & res)225 ani_status GetNotificationActionButtonArray(ani_env *env, ani_object param,
226 const char *name, std::vector<std::shared_ptr<NotificationActionButton>> &res)
227 {
228 ANS_LOGD("GetActionButtonArray call");
229 if (env == nullptr || param == nullptr || name == nullptr) {
230 ANS_LOGE("GetActionButtonArray failed, has nullptr");
231 return ANI_ERROR;
232 }
233 ani_ref arrayObj = nullptr;
234 ani_boolean isUndefined = true;
235 ani_status status;
236 ani_double length;
237 StsActionButton actionButton;
238 if ((status = GetPropertyRef(env, param, name, isUndefined, arrayObj)) != ANI_OK || isUndefined == ANI_TRUE) {
239 ANS_LOGE("GetActionButtonArray: GetPropertyRef name = %{public}s, status = %{public}d", name, status);
240 return ANI_INVALID_ARGS;
241 }
242 if (ANI_OK!= (status = GetPropertyDouble(env, static_cast<ani_object>(arrayObj), "length", isUndefined, length))) {
243 ANS_LOGE("GetActionButtonArray: GetPropertyDouble name = %{public}s, status = %{public}d", name, status);
244 return status;
245 }
246 for (int i = 0; i < static_cast<int>(length); i++) {
247 ani_ref buttonRef;
248 if (ANI_OK != (status = env->Object_CallMethodByName_Ref(static_cast<ani_object>(arrayObj),
249 "$_get", "I:Lstd/core/Object;", &buttonRef, (ani_int)i))) {
250 ANS_LOGE("GetActionButtonArray: get ref failed, status = %{public}d, index = %{public}d", status, i);
251 return status;
252 }
253 if (ANI_OK
254 != (status = UnwrapNotificationActionButton(env, static_cast<ani_object>(buttonRef), actionButton))) {
255 ANS_LOGE("GetActionButtonArray: UnwrapActionButton failed, status = %{public}d, index = %{public}d",
256 status, i);
257 return status;
258 }
259 std::shared_ptr<NotificationActionButton> button
260 = NotificationActionButton::Create(actionButton.icon,
261 actionButton.title, actionButton.wantAgent, actionButton.extras,
262 actionButton.semanticActionButton, actionButton.autoCreatedReplies, actionButton.mimeTypeOnlyInputs,
263 actionButton.userInput, actionButton.isContextual);
264 res.push_back(button);
265 }
266 ANS_LOGD("GetActionButtonArray end");
267 return status;
268 }
269
GetAniArrayNotificationActionButton(ani_env * env,const std::vector<std::shared_ptr<NotificationActionButton>> & actionButtons)270 ani_object GetAniArrayNotificationActionButton(ani_env* env,
271 const std::vector<std::shared_ptr<NotificationActionButton>> &actionButtons)
272 {
273 ANS_LOGD("GetAniArrayActionButton call");
274 if (env == nullptr || actionButtons.empty()) {
275 ANS_LOGE("GetAniArrayActionButton failed, has nullptr");
276 return nullptr;
277 }
278 ani_object arrayObj = newArrayClass(env, actionButtons.size());
279 if (arrayObj == nullptr) {
280 ANS_LOGE("GetAniArrayActionButton: arrayObj is nullptr");
281 return nullptr;
282 }
283 ani_size index = 0;
284 for (auto &button : actionButtons) {
285 ani_object item = WrapNotificationActionButton(env, button);
286 if (item == nullptr) {
287 ANS_LOGE("GetAniArrayActionButton: item is nullptr");
288 return nullptr;
289 }
290 if (ANI_OK != env->Object_CallMethodByName_Void(arrayObj, "$_set", "ILstd/core/Object;:V", index, item)) {
291 ANS_LOGE("GetAniArrayActionButton: Object_CallMethodByName_Void failed");
292 return nullptr;
293 }
294 index ++;
295 }
296 ANS_LOGD("GetAniArrayActionButton end");
297 return arrayObj;
298 }
299 }
300 }