1 /* 2 * Copyright (c) 2024 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 "notification_manager_impl.h" 17 #include "notification_utils.h" 18 #include "inner_errors.h" 19 #include "notification_enable.h" 20 #include "notification_manager_log.h" 21 #include "pixel_map_impl.h" 22 23 namespace OHOS { 24 namespace CJSystemapi { 25 26 using namespace OHOS::Notification; 27 using namespace OHOS::CJSystemapi::Notification; 28 ParseParameters(CNotificationRequest params,NotificationRequest & request)29 static bool ParseParameters(CNotificationRequest params, NotificationRequest &request) 30 { 31 if (!GetNotificationRequestByNumber(params, request)) { 32 return false; 33 } 34 35 if (!GetNotificationRequestByString(params, request)) { 36 return false; 37 } 38 39 if (!GetNotificationRequestByBool(params, request)) { 40 return false; 41 } 42 43 if (!GetNotificationRequestByCustom(params, request)) { 44 return false; 45 } 46 return true; 47 } 48 ParseBundleOption(CNotificationBundleOption & option,NotificationBundleOption & bundleOption)49 static bool ParseBundleOption(CNotificationBundleOption &option, NotificationBundleOption &bundleOption) 50 { 51 char bundle[STR_MAX_SIZE] = {0}; 52 if (strcpy_s(bundle, STR_MAX_SIZE, option.bundle) != EOK) { 53 return false; 54 } 55 bundleOption.SetBundleName(std::string(bundle)); 56 int32_t uid = option.uid; 57 bundleOption.SetUid(uid); 58 return true; 59 } 60 Publish(CNotificationRequest cjRequest)61 int NotificationManagerImpl::Publish(CNotificationRequest cjRequest) 62 { 63 NotificationRequest request; 64 if (!ParseParameters(cjRequest, request)) { 65 return ERROR_PARAM_INVALID; 66 } 67 int code = NotificationHelper::PublishNotification(request); 68 return ErrorToExternal(code); 69 } 70 Cancel(int32_t id,const char * label)71 int NotificationManagerImpl::Cancel(int32_t id, const char* label) 72 { 73 int code = NotificationHelper::CancelNotification(label, id); 74 return ErrorToExternal(code); 75 } 76 CancelAll()77 int NotificationManagerImpl::CancelAll() 78 { 79 int code = NotificationHelper::CancelAllNotifications(); 80 return ErrorToExternal(code); 81 } 82 AddSlot(int32_t type)83 int NotificationManagerImpl::AddSlot(int32_t type) 84 { 85 NotificationConstant::SlotType slot = NotificationConstant::SlotType::OTHER; 86 if (!SlotTypeCJToC(SlotType(type), slot)) { 87 return ERROR_PARAM_INVALID; 88 } 89 int code = NotificationHelper::AddSlotByType(slot); 90 return ErrorToExternal(code); 91 } 92 GetSlot(int32_t type,int32_t & errCode)93 CNotificationSlot NotificationManagerImpl::GetSlot(int32_t type, int32_t &errCode) 94 { 95 CNotificationSlot notificationSlot = { 96 .notificationType = 0, 97 .level = 0, 98 .desc = NULL, 99 .badgeFlag = false, 100 .bypassDnd = false, 101 .lockscreenVisibility = 0, 102 .vibrationEnabled = false, 103 .sound = NULL, 104 .lightEnabled = false, 105 .lightColor = 0, 106 .vibrationValues = { .head = NULL, .size = 0 }, 107 .enabled = false 108 }; 109 NotificationConstant::SlotType slotType = NotificationConstant::SlotType::OTHER; 110 if (!SlotTypeCJToC(SlotType(type), slotType)) { 111 errCode = ERROR_PARAM_INVALID; 112 return notificationSlot; 113 } 114 115 sptr<NotificationSlot> slot = nullptr; 116 errCode = ErrorToExternal(NotificationHelper::GetNotificationSlot(slotType, slot)); 117 if (slot != nullptr && !SetNotificationSlot(*slot, notificationSlot)) { 118 errCode = ERROR_PARAM_INVALID; 119 } 120 return notificationSlot; 121 } 122 GetSlots(int32_t & errCode)123 CArrayNotificationSlots NotificationManagerImpl::GetSlots(int32_t &errCode) 124 { 125 CArrayNotificationSlots notificationSlots = { .head = nullptr, .size = 0 }; 126 std::vector<sptr<NotificationSlot>> slots; 127 errCode = ErrorToExternal(NotificationHelper::GetNotificationSlots(slots)); 128 CNotificationSlot* head = 129 reinterpret_cast<CNotificationSlot *>(malloc(sizeof(CNotificationSlot) * slots.size())); 130 if (head == nullptr) { 131 LOGE("malloc CNotificationSlot failed"); 132 return notificationSlots; 133 } 134 int32_t count = 0; 135 for (auto vec : slots) { 136 if (!vec) { 137 LOGE("Invalidated NotificationSlot object ptr."); 138 continue; 139 } 140 if (!SetNotificationSlot(*vec, head[count])) { 141 LOGE("SetNotificationSlot is nullptr."); 142 continue; 143 } 144 count++; 145 } 146 notificationSlots.size = static_cast<int64_t>(slots.size()); 147 notificationSlots.head = head; 148 return notificationSlots; 149 } 150 RemoveSlot(int32_t type)151 int NotificationManagerImpl::RemoveSlot(int32_t type) 152 { 153 NotificationConstant::SlotType slot = NotificationConstant::SlotType::OTHER; 154 if (!SlotTypeCJToC(SlotType(type), slot)) { 155 return ERROR_PARAM_INVALID; 156 } 157 int code = NotificationHelper::RemoveNotificationSlot(slot); 158 return ErrorToExternal(code); 159 } 160 RemoveAllSlots()161 int NotificationManagerImpl::RemoveAllSlots() 162 { 163 int code = NotificationHelper::RemoveAllSlots(); 164 return ErrorToExternal(code); 165 } 166 GetActiveNotificationCount()167 RetDataUI32 NotificationManagerImpl::GetActiveNotificationCount() 168 { 169 RetDataUI32 ret = { .code = 0, .data = 0 }; 170 uint64_t num = 0; 171 int code = NotificationHelper::GetActiveNotificationNums(num); 172 ret.code = static_cast<uint32_t>(ErrorToExternal(code)); 173 ret.data = static_cast<uint32_t>(num); 174 return ret; 175 } 176 GetActiveNotifications(int32_t & errCode)177 CArrayNotificationRequest NotificationManagerImpl::GetActiveNotifications(int32_t &errCode) 178 { 179 CArrayNotificationRequest notificationRequests = { .head = nullptr, .size = 0 }; 180 std::vector<sptr<NotificationRequest>> requests; 181 int code = NotificationHelper::GetActiveNotifications(requests); 182 errCode = ErrorToExternal(code); 183 if (code != ERR_OK) { 184 return notificationRequests; 185 } 186 CNotificationRequest** head = 187 reinterpret_cast<CNotificationRequest **>(malloc(sizeof(CNotificationRequest*) * requests.size())); 188 if (head == nullptr) { 189 return notificationRequests; 190 } 191 notificationRequests.size = static_cast<int64_t>(requests.size()); 192 int32_t count = 0; 193 for (auto vec : requests) { 194 if (!vec) { 195 LOGI("Invalid NotificationRequest object ptr"); 196 continue; 197 } 198 head[count] = reinterpret_cast<CNotificationRequest *>(malloc(sizeof(CNotificationRequest))); 199 if (head[count] == nullptr) { 200 LOGE("NotificationManagerImpl::GetActiveNotifications malloc CNotificationRequest failed"); 201 for (int32_t i = 0 ; i < count; i++) { 202 free(head[i]); 203 } 204 free(head); 205 head = nullptr; 206 break; 207 } 208 if (!SetNotificationRequest(vec.GetRefPtr(), *(head[count]))) { 209 LOGI("Set NotificationRequest object failed"); 210 continue; 211 } 212 count++; 213 } 214 notificationRequests.head = head; 215 return notificationRequests; 216 } 217 CancelGroup(const char * cGroupName)218 int NotificationManagerImpl::CancelGroup(const char* cGroupName) 219 { 220 std::string groupName(cGroupName); 221 int code = NotificationHelper::CancelGroup(groupName); 222 return ErrorToExternal(code); 223 } 224 IsSupportTemplate(const char * cTemplateName)225 RetDataBool NotificationManagerImpl::IsSupportTemplate(const char* cTemplateName) 226 { 227 RetDataBool ret = { .code = 0, .data = false }; 228 std::string templateName(cTemplateName); 229 bool isSupport = false; 230 int code = NotificationHelper::IsSupportTemplate(templateName, isSupport); 231 ret.code = ErrorToExternal(code); 232 ret.data = isSupport; 233 return ret; 234 } 235 SetNotificationEnable(CNotificationBundleOption option,bool enable)236 int NotificationManagerImpl::SetNotificationEnable(CNotificationBundleOption option, bool enable) 237 { 238 NotificationBundleOption bundleOption; 239 if (!ParseBundleOption(option, bundleOption)) { 240 return ERROR_PARAM_INVALID; 241 } 242 std::string deviceId {""}; 243 int code = NotificationHelper::SetNotificationsEnabledForSpecifiedBundle(bundleOption, deviceId, enable); 244 return ErrorToExternal(code); 245 } 246 DisplayBadge(CNotificationBundleOption option,bool enable)247 int NotificationManagerImpl::DisplayBadge(CNotificationBundleOption option, bool enable) 248 { 249 NotificationBundleOption bundleOption; 250 if (!ParseBundleOption(option, bundleOption)) { 251 return ERROR_PARAM_INVALID; 252 } 253 int code = NotificationHelper::SetShowBadgeEnabledForBundle(bundleOption, enable); 254 return ErrorToExternal(code); 255 } 256 IsBadgeDisplayed(CNotificationBundleOption option)257 RetDataBool NotificationManagerImpl::IsBadgeDisplayed(CNotificationBundleOption option) 258 { 259 NotificationBundleOption bundleOption; 260 RetDataBool ret = { .code = 0, .data = false }; 261 if (!ParseBundleOption(option, bundleOption)) { 262 ret.code = ERROR_PARAM_INVALID; 263 return ret; 264 } 265 bool enabled = false; 266 int code = NotificationHelper::GetShowBadgeEnabledForBundle(bundleOption, enabled); 267 ret.code = ErrorToExternal(code); 268 ret.data = enabled; 269 return ret; 270 } 271 SetSlotFlagsByBundle(CNotificationBundleOption option,int32_t slotFlags)272 int NotificationManagerImpl::SetSlotFlagsByBundle(CNotificationBundleOption option, int32_t slotFlags) 273 { 274 NotificationBundleOption bundleOption; 275 if (!ParseBundleOption(option, bundleOption)) { 276 return ERROR_PARAM_INVALID; 277 } 278 int code = NotificationHelper::SetNotificationSlotFlagsAsBundle(bundleOption, slotFlags); 279 return ErrorToExternal(code); 280 } 281 GetSlotFlagsByBundle(CNotificationBundleOption option)282 RetDataUI32 NotificationManagerImpl::GetSlotFlagsByBundle(CNotificationBundleOption option) 283 { 284 RetDataUI32 ret = { .code = 0, .data = 0 }; 285 uint32_t slotFlags = 0; 286 NotificationBundleOption bundleOption; 287 if (!ParseBundleOption(option, bundleOption)) { 288 ret.code = ERROR_PARAM_INVALID; 289 return ret; 290 } 291 int code = NotificationHelper::GetNotificationSlotFlagsAsBundle(bundleOption, slotFlags); 292 ret.code = static_cast<uint32_t>(ErrorToExternal(code)); 293 ret.data = slotFlags; 294 return ret; 295 } 296 GetSlotNumByBundle(CNotificationBundleOption option)297 RetDataUI32 NotificationManagerImpl::GetSlotNumByBundle(CNotificationBundleOption option) 298 { 299 RetDataUI32 ret = { .code = 0, .data = 0 }; 300 uint64_t num = 0; 301 NotificationBundleOption bundleOption; 302 if (!ParseBundleOption(option, bundleOption)) { 303 ret.code = ERROR_PARAM_INVALID; 304 return ret; 305 } 306 int code = NotificationHelper::GetNotificationSlotNumAsBundle(bundleOption, num); 307 ret.code = static_cast<uint32_t>(ErrorToExternal(code)); 308 ret.data = static_cast<uint32_t>(num); 309 return ret; 310 } 311 RemoveGroupByBundle(CNotificationBundleOption option,const char * cGroupName)312 int NotificationManagerImpl::RemoveGroupByBundle(CNotificationBundleOption option, const char* cGroupName) 313 { 314 NotificationBundleOption bundleOption; 315 if (!ParseBundleOption(option, bundleOption)) { 316 return ERROR_PARAM_INVALID; 317 } 318 std::string groupName(cGroupName); 319 int code = NotificationHelper::RemoveGroupByBundle(bundleOption, groupName); 320 return ErrorToExternal(code); 321 } 322 IsNotificationEnabled()323 RetDataBool NotificationManagerImpl::IsNotificationEnabled() 324 { 325 RetDataBool ret = { .code = EINVAL, .data = false }; 326 IsEnableParams params {}; 327 bool allowed = false; 328 int errorCode; 329 if (params.hasBundleOption) { 330 LOGI("option.bundle : %{public}s option.uid : %{public}d", 331 params.option.GetBundleName().c_str(), 332 params.option.GetUid()); 333 errorCode = NotificationHelper::IsAllowedNotify(params.option, allowed); 334 } else if (params.hasUserId) { 335 LOGI("userId : %{public}d", params.userId); 336 errorCode = NotificationHelper::IsAllowedNotify(params.userId, allowed); 337 } else { 338 errorCode = NotificationHelper::IsAllowedNotifySelf(allowed); 339 } 340 ret.code = ErrorToExternal(errorCode); 341 ret.data = allowed; 342 LOGI("errorCode : %{public}d, allowed : %{public}d", 343 errorCode, allowed); 344 return ret; 345 } 346 SetBadgeNumber(int32_t badgeNumber)347 int NotificationManagerImpl::SetBadgeNumber(int32_t badgeNumber) 348 { 349 int code = NotificationHelper::SetBadgeNumber(badgeNumber); 350 return ErrorToExternal(code); 351 } 352 RequestEnableNotification()353 int NotificationManagerImpl::RequestEnableNotification() 354 { 355 IsEnableParams params {}; 356 std::string deviceId {""}; 357 sptr<AnsDialogHostClient> client = nullptr; 358 if (!AnsDialogHostClient::CreateIfNullptr(client)) { 359 LOGI("dialog is popping %{public}d.", ERR_ANS_DIALOG_IS_POPPING) 360 return ErrorToExternal(ERR_ANS_DIALOG_IS_POPPING); 361 } 362 int code = NotificationHelper::RequestEnableNotification(deviceId, client, params.callerToken); 363 LOGI("done, code is %{public}d.", code) 364 return ErrorToExternal(code); 365 } 366 RequestEnableNotificationWithContext(sptr<AbilityRuntime::CJAbilityContext> context)367 int NotificationManagerImpl::RequestEnableNotificationWithContext(sptr<AbilityRuntime::CJAbilityContext> context) 368 { 369 IsEnableParams params {}; 370 sptr<IRemoteObject> callerToken = context->GetToken(); 371 params.callerToken = callerToken; 372 sptr<AnsDialogHostClient> client = nullptr; 373 params.hasCallerToken = true; 374 std::string deviceId {""}; 375 if (!AnsDialogHostClient::CreateIfNullptr(client)) { 376 LOGI("dialog is popping %{public}d.", ERR_ANS_DIALOG_IS_POPPING) 377 return ErrorToExternal(ERR_ANS_DIALOG_IS_POPPING); 378 } 379 int code = NotificationHelper::RequestEnableNotification(deviceId, client, params.callerToken); 380 LOGI("done, code is %{public}d.", code) 381 return ErrorToExternal(code); 382 } 383 IsDistributedEnabled()384 RetDataBool NotificationManagerImpl::IsDistributedEnabled() 385 { 386 RetDataBool ret = { .code = EINVAL, .data = false }; 387 bool enable = false; 388 int code = NotificationHelper::IsDistributedEnabled(enable); 389 LOGI("IsDistributedEnabled enable = %{public}d", enable); 390 ret.code = code; 391 ret.data = enable; 392 return ret; 393 } 394 } // CJSystemapi 395 } // namespace OHOS