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_slot.h"
16
17 #include "ans_log_wrapper.h"
18 #include "sts_notification_manager.h"
19 #include "sts_common.h"
20
21
22 namespace OHOS {
23 namespace NotificationSts {
SetOptionalFieldSlotLevel(ani_env * env,const ani_class cls,ani_object & object,const std::string fieldName,const SlotLevel value)24 bool SetOptionalFieldSlotLevel(
25 ani_env *env, const ani_class cls, ani_object &object, const std::string fieldName, const SlotLevel value)
26 {
27 ANS_LOGD("SetOptionalFieldSlotLevel call");
28 if (env == nullptr || cls == nullptr || object == nullptr) {
29 ANS_LOGE("SetOptionalFieldSlotLevel failed, has nullptr");
30 return false;
31 }
32 ani_field field = nullptr;
33 ani_status status = env->Class_FindField(cls, fieldName.c_str(), &field);
34 if (status != ANI_OK || field == nullptr) {
35 ANS_LOGE("Class_FindField failed or null field, status=%{public}d, fieldName=%{public}s",
36 status, fieldName.c_str());
37 return false;
38 }
39 ani_enum_item enumItem = nullptr;
40 NotificationSts::SlotLevelCToEts(env, value, enumItem);
41 if (enumItem == nullptr) {
42 ANS_LOGE("null enumItem");
43 return false;
44 }
45 status = env->Object_SetField_Ref(object, field, enumItem);
46 if (status != ANI_OK) {
47 ANS_LOGE("Object_SetField_Ref failed, status=%{public}d, fieldName=%{public}s",
48 status, fieldName.c_str());
49 return false;
50 }
51 return true;
52 }
53
SetOptionalFieldSlotType(ani_env * env,const ani_class cls,ani_object & object,const std::string fieldName,const SlotType value)54 bool SetOptionalFieldSlotType(
55 ani_env *env, const ani_class cls, ani_object &object, const std::string fieldName, const SlotType value)
56 {
57 ANS_LOGD("SetOptionalFieldSlotType call");
58 if (env == nullptr || cls == nullptr || object == nullptr) {
59 ANS_LOGE("SetOptionalFieldSlotType failed, has nullptr");
60 return false;
61 }
62 ani_field field = nullptr;
63 ani_status status = env->Class_FindField(cls, fieldName.c_str(), &field);
64 if (status != ANI_OK || field == nullptr) {
65 ANS_LOGE("Class_FindField failed or null field, status=%{public}d, fieldName=%{public}s",
66 status, fieldName.c_str());
67 return false;
68 }
69 ani_enum_item enumItem = nullptr;
70 NotificationSts::SlotTypeCToEts(env, value, enumItem);
71 if (enumItem == nullptr) {
72 ANS_LOGE("null enumItem");
73 return false;
74 }
75 status = env->Object_SetField_Ref(object, field, enumItem);
76 if (status != ANI_OK) {
77 ANS_LOGE("Object_SetField_Ref failed, status=%{public}d, fieldName=%{public}s",
78 status, fieldName.c_str());
79 return false;
80 }
81 return true;
82 }
83
WrapNotificationSlotByBoolean(ani_env * env,sptr<Notification::NotificationSlot> slot,ani_object & outAniObj)84 bool WrapNotificationSlotByBoolean(ani_env *env, sptr<Notification::NotificationSlot> slot, ani_object &outAniObj)
85 {
86 if (!SetPropertyOptionalByBoolean(env, outAniObj, "badgeFlag", slot->IsShowBadge())) {
87 ANS_LOGE("Set badgeFlag fail");
88 return false;
89 }
90 if (!SetPropertyOptionalByBoolean(env, outAniObj, "bypassDnd", slot->IsEnableBypassDnd())) {
91 ANS_LOGE("Set bypassDnd fail");
92 return false;
93 }
94 if (!SetPropertyOptionalByBoolean(env, outAniObj, "vibrationEnabled", slot->CanVibrate())) {
95 ANS_LOGE("Set vibrationEnabled fail");
96 return false;
97 }
98 if (!SetPropertyOptionalByBoolean(env, outAniObj, "lightEnabled", slot->CanEnableLight())) {
99 ANS_LOGE("Set lightEnabled fail");
100 return false;
101 }
102 if (!SetPropertyOptionalByBoolean(env, outAniObj, "enabled", slot->GetEnable())) {
103 ANS_LOGE("Set enabled fail");
104 return false;
105 }
106 return true;
107 }
108
WrapNotificationSlotByString(ani_env * env,sptr<Notification::NotificationSlot> slot,ani_object & outAniObj)109 bool WrapNotificationSlotByString(ani_env *env, sptr<Notification::NotificationSlot> slot, ani_object &outAniObj)
110 {
111 if (!SetPropertyOptionalByString(env, outAniObj, "desc", slot->GetDescription())) {
112 ANS_LOGE("Set desc fail");
113 return false;
114 }
115 if (!SetPropertyOptionalByString(env, outAniObj, "sound", slot->GetSound().ToString().c_str())) {
116 ANS_LOGE("Set sound fail");
117 return false;
118 }
119 return true;
120 }
121
WrapNotificationSlotByDouble(ani_env * env,sptr<Notification::NotificationSlot> slot,ani_object & outAniObj)122 bool WrapNotificationSlotByDouble(ani_env *env, sptr<Notification::NotificationSlot> slot, ani_object &outAniObj)
123 {
124 if (!SetPropertyOptionalByDouble(
125 env, outAniObj, "lockscreenVisibility", static_cast<double>(slot->GetLockScreenVisibleness()))) {
126 ANS_LOGE("Set lockscreenVisibility fail");
127 return false;
128 }
129 if (!SetPropertyOptionalByDouble(env, outAniObj, "lightColor", static_cast<double>(slot->GetLedLightColor()))) {
130 ANS_LOGE("Set lightColor fail");
131 return false;
132 }
133 if (!SetPropertyOptionalByDouble(env, outAniObj, "reminderMode", static_cast<double>(slot->GetReminderMode()))) {
134 ANS_LOGE("Set reminderMode fail");
135 return false;
136 }
137 if (!SetPropertyOptionalByDouble(
138 env, outAniObj, "authorizedStatus", static_cast<double>(slot->GetAuthorizedStatus()))) {
139 ANS_LOGE("Set authorizedStatus fail");
140 return false;
141 }
142 return true;
143 }
144
WrapNotificationSlot(ani_env * env,sptr<Notification::NotificationSlot> slot,ani_object & outAniObj)145 bool WrapNotificationSlot(ani_env *env, sptr<Notification::NotificationSlot> slot, ani_object &outAniObj)
146 {
147 ANS_LOGD("WrapNotificationSlot call");
148 if (env == nullptr || slot == nullptr) {
149 ANS_LOGE("WrapNotificationSlot failed, has nullptr");
150 return false;
151 }
152 ani_class cls;
153 if (!CreateClassObjByClassName(env, NOTIFICATION_SOLT_CLASSNAME, cls, outAniObj)) {
154 ANS_LOGE("CreateClassObjByClassName fail");
155 return false;
156 }
157 if (cls == nullptr || outAniObj == nullptr) {
158 ANS_LOGE("Create class failed");
159 return false;
160 }
161
162 if (!SetOptionalFieldSlotType(env, cls, outAniObj, "notificationType", slot->GetType())) {
163 ANS_LOGE("Set notificationType fail");
164 return false;
165 }
166 if (!SetOptionalFieldSlotLevel(env, cls, outAniObj, "notificationLevel", slot->GetLevel())) {
167 ANS_LOGE("Set notificationLevel fail");
168 return false;
169 }
170 if (!WrapNotificationSlotByBoolean(env, slot, outAniObj)) {
171 ANS_LOGE("set Boolean params fail");
172 return false;
173 }
174 if (!WrapNotificationSlotByString(env, slot, outAniObj)) {
175 ANS_LOGE("set String params fail");
176 return false;
177 }
178 if (!WrapNotificationSlotByDouble(env, slot, outAniObj)) {
179 ANS_LOGE("set String params fail");
180 return false;
181 }
182 if (!SetOptionalFieldArrayDouble(env, cls, outAniObj, "vibrationValues", slot->GetVibrationStyle())) {
183 ANS_LOGE("Set vibrationValues fail");
184 return false;
185 }
186 ANS_LOGD("WrapNotificationSlot end");
187 return true;
188 }
189
WrapNotificationSlotArray(ani_env * env,const std::vector<sptr<Notification::NotificationSlot>> & slots,ani_object & outAniObj)190 bool WrapNotificationSlotArray(ani_env *env, const std::vector<sptr<Notification::NotificationSlot>>& slots,
191 ani_object &outAniObj)
192 {
193 ANS_LOGD("WrapNotificationSlotArray call");
194 outAniObj = newArrayClass(env, slots.size());
195 if (outAniObj == nullptr) {
196 ANS_LOGE("outAniObj is null, newArrayClass Faild");
197 return false;
198 }
199 int index = 0;
200 for (auto &it : slots) {
201 ani_object infoObj;
202 if (!WrapNotificationSlot(env, it, infoObj) || infoObj == nullptr) {
203 ANS_LOGE("WrapNotificationSlot Faild. index = %{public}d", index);
204 return false;
205 }
206 if (ANI_OK != env->Object_CallMethodByName_Void(outAniObj, "$_set", "ILstd/core/Object;:V", index, infoObj)) {
207 ANS_LOGE("set Faild. index = %{public}d", index);
208 return false;
209 }
210 index++;
211 }
212 ANS_LOGD("WrapNotificationSlotArray end");
213 return true;
214 }
215
ParseNotificationSlotByBasicType(ani_env * env,ani_object notificationSlotObj,NotificationSlot & slot)216 bool ParseNotificationSlotByBasicType(ani_env *env, ani_object notificationSlotObj, NotificationSlot &slot)
217 {
218 if (notificationSlotObj == nullptr) {
219 ANS_LOGE("notificationSlotObj is null");
220 return false;
221 }
222 ani_boolean isUndefined = ANI_TRUE;
223 std::string desc = "";
224 if (GetPropertyString(env, notificationSlotObj, "desc", isUndefined, desc) == ANI_OK && isUndefined == ANI_FALSE) {
225 slot.SetDescription(GetResizeStr(desc, STR_MAX_SIZE));
226 }
227 std::string sound = "";
228 if (GetPropertyString(env, notificationSlotObj, "sound", isUndefined, sound) == ANI_OK &&
229 isUndefined == ANI_FALSE) {
230 slot.SetSound(Uri(GetResizeStr(sound, STR_MAX_SIZE)));
231 }
232 ani_double doubleValue = 0.0;
233 if (GetPropertyDouble(env, notificationSlotObj, "lockscreenVisibility", isUndefined, doubleValue) == ANI_OK
234 && isUndefined == ANI_FALSE) {
235 slot.SetLockscreenVisibleness(
236 Notification::NotificationConstant::VisiblenessType(static_cast<int32_t>(doubleValue)));
237 }
238 if (GetPropertyDouble(env, notificationSlotObj, "lightColor", isUndefined, doubleValue) == ANI_OK
239 && isUndefined == ANI_FALSE) {
240 slot.SetLedLightColor(static_cast<int32_t>(doubleValue));
241 }
242 bool boolValue = true;
243 if (GetPropertyBool(env, notificationSlotObj, "badgeFlag", isUndefined, boolValue) == ANI_OK
244 && isUndefined == ANI_FALSE) {
245 slot.EnableBadge(boolValue);
246 }
247 if (GetPropertyBool(env, notificationSlotObj, "bypassDnd", isUndefined, boolValue) == ANI_OK
248 && isUndefined == ANI_FALSE) {
249 slot.EnableBypassDnd(boolValue);
250 }
251 if (GetPropertyBool(env, notificationSlotObj, "lightEnabled", isUndefined, boolValue) == ANI_OK
252 && isUndefined == ANI_FALSE) {
253 slot.SetEnableLight(boolValue);
254 }
255 if (GetPropertyBool(env, notificationSlotObj, "vibrationEnabled", isUndefined, boolValue) == ANI_OK
256 && isUndefined == ANI_FALSE) {
257 slot.SetEnableVibration(boolValue);
258 }
259 return true;
260 }
261
UnwrapNotificationSlot(ani_env * env,ani_object notificationSlotObj,NotificationSlot & slot)262 bool UnwrapNotificationSlot(ani_env *env, ani_object notificationSlotObj, NotificationSlot &slot)
263 {
264 ANS_LOGD("UnwrapNotificationSlot enter");
265 if (notificationSlotObj == nullptr) {
266 ANS_LOGE("notificationSlotObj is null");
267 return false;
268 }
269 ani_status status = ANI_ERROR;
270 ani_boolean isUndefined = ANI_TRUE;
271 ani_ref notificationTypeRef = {};
272 status = GetPropertyRef(env, notificationSlotObj, "notificationType", isUndefined, notificationTypeRef);
273 if (status == ANI_OK && isUndefined == ANI_FALSE) {
274 Notification::NotificationConstant::SlotType slotType = Notification::NotificationConstant::SlotType::OTHER;
275 if (SlotTypeEtsToC(env, static_cast<ani_enum_item>(notificationTypeRef), slotType)) {
276 slot.SetType(slotType);
277 }
278 }
279 status = GetPropertyRef(env, notificationSlotObj, "notificationLevel", isUndefined, notificationTypeRef);
280 if (status == ANI_OK && isUndefined == ANI_FALSE) {
281 NotificationSlot::NotificationLevel outLevel {NotificationSlot::NotificationLevel::LEVEL_NONE};
282 if (SlotLevelEtsToC(env, static_cast<ani_enum_item>(notificationTypeRef), outLevel)) {
283 slot.SetLevel(outLevel);
284 }
285 }
286 if (!ParseNotificationSlotByBasicType(env, notificationSlotObj, slot)) {
287 ANS_LOGE("ParseNotificationSlotByBasicType failed");
288 return false;
289 }
290 std::vector<int64_t> vibrationValues;
291 if (GetPropertyNumberArray(env, notificationSlotObj, "vibrationValues", isUndefined, vibrationValues) == ANI_OK &&
292 isUndefined == ANI_FALSE) {
293 slot.SetVibrationStyle(vibrationValues);
294 }
295 ANS_LOGD("UnwrapNotificationSlot leave");
296 return true;
297 }
298
UnwrapNotificationSlotArrayByAniObj(ani_env * env,ani_object notificationSlotArrayObj,std::vector<NotificationSlot> & slots)299 bool UnwrapNotificationSlotArrayByAniObj(ani_env *env, ani_object notificationSlotArrayObj,
300 std::vector<NotificationSlot> &slots)
301 {
302 ANS_LOGD("UnwrapNotificationSlotArrayByAniObj enter");
303 if (notificationSlotArrayObj == nullptr) {
304 ANS_LOGE("notificationSlotArrayObj is null");
305 return false;
306 }
307 ani_double length;
308 ani_status status = env->Object_GetPropertyByName_Double(notificationSlotArrayObj, "length", &length);
309 if (status != ANI_OK) {
310 ANS_LOGE("Object_GetPropertyByName_Double faild. status : %{public}d", status);
311 return false;
312 }
313 for (int i = 0; i < int(length); i++) {
314 ani_ref notificationSlotEntryRef;
315 status = env->Object_CallMethodByName_Ref(notificationSlotArrayObj,
316 "$_get", "I:Lstd/core/Object;", ¬ificationSlotEntryRef, (ani_int)i);
317 if (status != ANI_OK) {
318 ANS_LOGE("Object_CallMethodByName_Ref faild. status : %{public}d", status);
319 }
320 NotificationSlot slot;
321 if (!UnwrapNotificationSlot(env, static_cast<ani_object>(notificationSlotEntryRef), slot)) {
322 ANS_LOGE("UnwrapNotificationSlot faild");
323 return false;
324 }
325 slots.emplace_back(slot);
326 }
327 ANS_LOGD("UnwrapNotificationSlotArrayByAniObj leave");
328 return true;
329 }
330 } // namespace NotificationSts
331 } // OHOS
332