1 /*
2 * Copyright (c) 2021-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 <memory>
17 
18 #include "notification_config_parse.h"
19 
20 #include "ans_log_wrapper.h"
21 #include "notification_trust_list.h"
22 #include "notification_slot.h"
23 #include "file_utils.h"
24 
25 namespace OHOS {
26 namespace Notification {
NotificationConfigParse()27 NotificationConfigParse::NotificationConfigParse()
28 {
29     if (!FileUtils::GetJsonByFilePath(NOTIFICAITON_CONFIG_FILE, notificationConfigJsons_)) {
30         ANS_LOGE("Failed to get notification config file, fileName: %{public}s.", NOTIFICAITON_CONFIG_FILE);
31     }
32     defaultCurrentSlotReminder_ = {
33         {NotificationConstant::SlotType::SOCIAL_COMMUNICATION, 0b111111},
34         {NotificationConstant::SlotType::SERVICE_REMINDER, 0b111111},
35         {NotificationConstant::SlotType::CONTENT_INFORMATION, 0b000000},
36         {NotificationConstant::SlotType::OTHER, 0b000000},
37         {NotificationConstant::SlotType::LIVE_VIEW, 0b111011},
38         {NotificationConstant::SlotType::CUSTOMER_SERVICE, 0b110001},
39         {NotificationConstant::SlotType::EMERGENCY_INFORMATION, 0b111111}
40     };
41 }
42 
GetConfigJson(const std::string & keyCheck,nlohmann::json & configJson) const43 bool NotificationConfigParse::GetConfigJson(const std::string &keyCheck, nlohmann::json &configJson) const
44 {
45     if (notificationConfigJsons_.size() <= 0) {
46         ANS_LOGE("Failed to get config json cause empty notificationConfigJsons.");
47         return false;
48     }
49     bool ret = false;
50     std::for_each(notificationConfigJsons_.rbegin(), notificationConfigJsons_.rend(),
51         [&keyCheck, &configJson, &ret](const nlohmann::json &json) {
52         if (keyCheck.find("/") == std::string::npos && json.contains(keyCheck)) {
53             configJson = json;
54             ret = true;
55         }
56 
57         if (keyCheck.find("/") != std::string::npos) {
58             nlohmann::json::json_pointer keyCheckPoint(keyCheck);
59             if (json.contains(keyCheckPoint)) {
60                 configJson = json;
61                 ret = true;
62             }
63         }
64     });
65     if (!ret) {
66         ANS_LOGE("Cannot find keyCheck: %{public}s in notificationConfigJsons.", keyCheck.c_str());
67     }
68     return ret;
69 }
70 
GetCurrentSlotReminder(std::map<NotificationConstant::SlotType,std::shared_ptr<NotificationFlags>> & currentSlotReminder) const71 bool NotificationConfigParse::GetCurrentSlotReminder(
72     std::map<NotificationConstant::SlotType, std::shared_ptr<NotificationFlags>> &currentSlotReminder) const
73 {
74     nlohmann::json root;
75     std::string slotJsonPoint = "/";
76     slotJsonPoint.append(CFG_KEY_NOTIFICATION_SERVICE);
77     slotJsonPoint.append("/");
78     slotJsonPoint.append(CFG_KEY_SLOT_TYPE_REMINDER);
79     if (!GetConfigJson(slotJsonPoint, root)) {
80         return false;
81     }
82 
83     if (root.find(CFG_KEY_NOTIFICATION_SERVICE) == root.end()) {
84         ANS_LOGE("GetCurrentSlotReminder failed as can not find notificationService.");
85         return false;
86     }
87     nlohmann::json currentDeviceRemindJson = root[CFG_KEY_NOTIFICATION_SERVICE][CFG_KEY_SLOT_TYPE_REMINDER];
88     if (currentDeviceRemindJson.is_null() || !currentDeviceRemindJson.is_array() || currentDeviceRemindJson.empty()) {
89         ANS_LOGE("GetCurrentSlotReminder failed as invalid currentDeviceReminder json.");
90         return false;
91     }
92     for (auto &reminderFilterSlot : currentDeviceRemindJson) {
93         NotificationConstant::SlotType slotType;
94         if (reminderFilterSlot.find(CFG_KEY_NAME) == reminderFilterSlot.end() ||
95             reminderFilterSlot[CFG_KEY_NAME].is_null() ||
96             !reminderFilterSlot[CFG_KEY_NAME].is_string() ||
97             !NotificationSlot::GetSlotTypeByString(reminderFilterSlot[CFG_KEY_NAME].get<std::string>(), slotType)) {
98             continue;
99         }
100 
101         std::shared_ptr<NotificationFlags> reminderFlags;
102         if (reminderFilterSlot.find(CFG_KEY_REMINDER_FLAGS) == reminderFilterSlot.end() ||
103             reminderFilterSlot[CFG_KEY_REMINDER_FLAGS].is_null() ||
104             !reminderFilterSlot[CFG_KEY_REMINDER_FLAGS].is_string() ||
105             !NotificationFlags::GetReminderFlagsByString(
106                 reminderFilterSlot[CFG_KEY_REMINDER_FLAGS].get<std::string>(), reminderFlags)) {
107             continue;
108         }
109         currentSlotReminder[slotType] = reminderFlags;
110     }
111     if (currentSlotReminder.size() <= 0) {
112         ANS_LOGE("GetCurrentSlotReminder failed as invalid currentSlotReminder size.");
113         return false;
114     }
115     return true;
116 }
117 
GetConfigSlotReminderModeByType(NotificationConstant::SlotType slotType) const118 uint32_t NotificationConfigParse::GetConfigSlotReminderModeByType(NotificationConstant::SlotType slotType) const
119 {
120     static std::map<NotificationConstant::SlotType, std::shared_ptr<NotificationFlags>> configSlotsReminder;
121     if (configSlotsReminder.empty()) {
122         GetCurrentSlotReminder(configSlotsReminder);
123     }
124 
125     auto iter = configSlotsReminder.find(slotType);
126     if (iter != configSlotsReminder.end()) {
127         return iter->second->GetReminderFlags();
128     }
129 
130     auto defaultIter = defaultCurrentSlotReminder_.find(slotType);
131     if (defaultIter != defaultCurrentSlotReminder_.end()) {
132         return defaultIter->second;
133     }
134 
135     return 0;
136 }
137 
GetConfigSlotReminderModeByType(NotificationConstant::SlotType slotType,const sptr<NotificationBundleOption> & bundleOption) const138 uint32_t NotificationConfigParse::GetConfigSlotReminderModeByType(NotificationConstant::SlotType slotType,
139     const sptr<NotificationBundleOption> &bundleOption) const
140 {
141     uint32_t reminderFlags = GetConfigSlotReminderModeByType(slotType);
142     if (DelayedSingleton<NotificationTrustList>::GetInstance()->IsSlotFlagsTrustlistAsBundle(bundleOption)) {
143         return reminderFlags & 0b111111;
144     }
145     return reminderFlags;
146 }
147 
GetFlowCtrlConfigFromCCM(FlowControlThreshold & threshold)148 void NotificationConfigParse::GetFlowCtrlConfigFromCCM(FlowControlThreshold &threshold)
149 {
150     nlohmann::json root;
151     std::string JsonPoint = "/";
152     JsonPoint.append(CFG_KEY_NOTIFICATION_SERVICE);
153     if (!GetConfigJson(JsonPoint, root)) {
154         ANS_LOGE("Failed to get JsonPoint CCM config file");
155         return;
156     }
157     if (!root.contains(CFG_KEY_NOTIFICATION_SERVICE)) {
158         ANS_LOGW("GetFlowCtrlConfigFromCCM not found jsonKey");
159         return;
160     }
161     nlohmann::json affects = root[CFG_KEY_NOTIFICATION_SERVICE];
162     if (affects.is_null() || affects.empty()) {
163         ANS_LOGE("GetFlowCtrlConfigFromCCM failed as invalid ccmFlowCtrlConfig json");
164         return;
165     }
166     if (affects.contains(CFG_KEY_MAX_CREATE_NUM_PERSECOND)) {
167         threshold.maxCreateNumPerSecond = affects[CFG_KEY_MAX_CREATE_NUM_PERSECOND];
168     }
169 
170     if (affects.contains(CFG_KEY_MAX_UPDATE_NUM_PERSECOND)) {
171         threshold.maxUpdateNumPerSecond = affects[CFG_KEY_MAX_UPDATE_NUM_PERSECOND];
172     }
173 
174     if (affects.contains(CFG_KEY_MAX_CREATE_NUM_PERSECOND_PERAPP)) {
175         threshold.maxCreateNumPerSecondPerApp = affects[CFG_KEY_MAX_CREATE_NUM_PERSECOND_PERAPP];
176     }
177 
178     if (affects.contains(CFG_KEY_MAX_UPDATE_NUM_PERSECOND_PERAPP)) {
179         threshold.maxUpdateNumPerSecondPerApp = affects[CFG_KEY_MAX_UPDATE_NUM_PERSECOND_PERAPP];
180     }
181 
182     ANS_LOGI("GetFlowCtrlConfigFromCCM success");
183 }
184 } // namespace Notification
185 } // namespace OHOS
186