• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifdef ENABLE_ANS_ADDITIONAL_CONTROL
22 #include "notification_extension_wrapper.h"
23 #endif
24 #include "notification_slot.h"
25 #include "file_utils.h"
26 
27 namespace OHOS {
28 namespace Notification {
NotificationConfigParse()29 NotificationConfigParse::NotificationConfigParse()
30 {
31     if (!FileUtils::GetJsonByFilePath(NOTIFICAITON_CONFIG_FILE, notificationConfigJsons_)) {
32         ANS_LOGE("Failed to get notification config file, fileName: %{public}s.", NOTIFICAITON_CONFIG_FILE);
33     }
34     defaultCurrentSlotReminder_ = {
35         {NotificationConstant::SlotType::SOCIAL_COMMUNICATION, 0b111111},
36         {NotificationConstant::SlotType::SERVICE_REMINDER, 0b111111},
37         {NotificationConstant::SlotType::CONTENT_INFORMATION, 0b000000},
38         {NotificationConstant::SlotType::OTHER, 0b000000},
39         {NotificationConstant::SlotType::LIVE_VIEW, 0b111011},
40         {NotificationConstant::SlotType::CUSTOMER_SERVICE, 0b110001},
41         {NotificationConstant::SlotType::EMERGENCY_INFORMATION, 0b111111}
42     };
43 }
44 
GetAppPrivileges(const std::string & bundleName) const45 std::shared_ptr<NotificationAppPrivileges> NotificationConfigParse::GetAppPrivileges(
46     const std::string &bundleName) const
47 {
48     nlohmann::json root;
49     std::string JsonPoint = "/";
50     JsonPoint.append(APP_PRIVILEGES);
51     if (!GetConfigJson(JsonPoint, root)) {
52         ANS_LOGE("Failed to get JsonPoint CCM config file.");
53         return nullptr;
54     }
55     if (!root.contains(APP_PRIVILEGES)) {
56         ANS_LOGW("not found jsonKey appPrivileges");
57         return nullptr;
58     }
59     nlohmann::json affects = root[APP_PRIVILEGES];
60     if (affects.is_null() || affects.empty()) {
61         ANS_LOGE("GetCcmPrivileges failed as invalid ccmPrivileges json.");
62         return nullptr;
63     }
64     for (auto &affect : affects.items()) {
65         if (affect.key() == bundleName) {
66             return std::make_shared<NotificationAppPrivileges>(affect.value());
67         }
68     }
69     return nullptr;
70 }
71 
GetConfigJson(const std::string & keyCheck,nlohmann::json & configJson) const72 bool NotificationConfigParse::GetConfigJson(const std::string &keyCheck, nlohmann::json &configJson) const
73 {
74     if (notificationConfigJsons_.size() <= 0) {
75         ANS_LOGE("Failed to get config json cause empty notificationConfigJsons.");
76         return false;
77     }
78     bool ret = false;
79     std::for_each(notificationConfigJsons_.rbegin(), notificationConfigJsons_.rend(),
80         [&keyCheck, &configJson, &ret](const nlohmann::json &json) {
81         if (keyCheck.find("/") == std::string::npos && json.contains(keyCheck)) {
82             configJson = json;
83             ret = true;
84         }
85 
86         if (keyCheck.find("/") != std::string::npos) {
87             nlohmann::json::json_pointer keyCheckPoint(keyCheck);
88             if (json.contains(keyCheckPoint)) {
89                 configJson = json;
90                 ret = true;
91             }
92         }
93     });
94     if (!ret) {
95         ANS_LOGE("Cannot find keyCheck: %{public}s in notificationConfigJsons.", keyCheck.c_str());
96     }
97     return ret;
98 }
99 
SetCurrentSlotReminder(std::map<NotificationConstant::SlotType,std::shared_ptr<NotificationFlags>> & currentSlotReminder,NotificationConstant::SlotType & slotType,std::shared_ptr<NotificationFlags> & reminderFlags)100 void NotificationConfigParse::SetCurrentSlotReminder(
101     std::map<NotificationConstant::SlotType, std::shared_ptr<NotificationFlags>> &currentSlotReminder,
102     NotificationConstant::SlotType &slotType, std::shared_ptr<NotificationFlags> &reminderFlags)
103 {
104     std::lock_guard<std::mutex> lock(slotReminderMutex_);
105     currentSlotReminder[slotType] = reminderFlags;
106 }
107 
GetCurrentSlotReminder(std::map<NotificationConstant::SlotType,std::shared_ptr<NotificationFlags>> & currentSlotReminder) const108 bool NotificationConfigParse::GetCurrentSlotReminder(
109     std::map<NotificationConstant::SlotType, std::shared_ptr<NotificationFlags>> &currentSlotReminder) const
110 {
111     nlohmann::json root;
112     std::string slotJsonPoint = "/";
113     slotJsonPoint.append(CFG_KEY_NOTIFICATION_SERVICE);
114     slotJsonPoint.append("/");
115     slotJsonPoint.append(CFG_KEY_SLOT_TYPE_REMINDER);
116     if (!GetConfigJson(slotJsonPoint, root)) {
117         return false;
118     }
119 
120     if (root.find(CFG_KEY_NOTIFICATION_SERVICE) == root.end()) {
121         ANS_LOGE("GetCurrentSlotReminder failed as can not find notificationService.");
122         return false;
123     }
124     nlohmann::json currentDeviceRemindJson = root[CFG_KEY_NOTIFICATION_SERVICE][CFG_KEY_SLOT_TYPE_REMINDER];
125     if (currentDeviceRemindJson.is_null() || !currentDeviceRemindJson.is_array() || currentDeviceRemindJson.empty()) {
126         ANS_LOGE("GetCurrentSlotReminder failed as invalid currentDeviceReminder json.");
127         return false;
128     }
129     for (auto &reminderFilterSlot : currentDeviceRemindJson) {
130         NotificationConstant::SlotType slotType;
131         if (reminderFilterSlot.find(CFG_KEY_NAME) == reminderFilterSlot.end() ||
132             reminderFilterSlot[CFG_KEY_NAME].is_null() ||
133             !reminderFilterSlot[CFG_KEY_NAME].is_string() ||
134             !NotificationSlot::GetSlotTypeByString(reminderFilterSlot[CFG_KEY_NAME].get<std::string>(), slotType)) {
135             continue;
136         }
137 
138         std::shared_ptr<NotificationFlags> reminderFlags;
139         if (reminderFilterSlot.find(CFG_KEY_REMINDER_FLAGS) == reminderFilterSlot.end() ||
140             reminderFilterSlot[CFG_KEY_REMINDER_FLAGS].is_null() ||
141             !reminderFilterSlot[CFG_KEY_REMINDER_FLAGS].is_string() ||
142             !NotificationFlags::GetReminderFlagsByString(
143                 reminderFilterSlot[CFG_KEY_REMINDER_FLAGS].get<std::string>(), reminderFlags)) {
144             continue;
145         }
146         DelayedSingleton<NotificationConfigParse>::GetInstance()->
147             SetCurrentSlotReminder(currentSlotReminder, slotType, reminderFlags);
148     }
149     if (currentSlotReminder.size() <= 0) {
150         ANS_LOGE("GetCurrentSlotReminder failed as invalid currentSlotReminder size.");
151         return false;
152     }
153     return true;
154 }
155 
GetConfigSlotReminderModeByType(NotificationConstant::SlotType slotType) const156 uint32_t NotificationConfigParse::GetConfigSlotReminderModeByType(NotificationConstant::SlotType slotType) const
157 {
158     static std::map<NotificationConstant::SlotType, std::shared_ptr<NotificationFlags>> configSlotsReminder;
159     if (configSlotsReminder.empty()) {
160         GetCurrentSlotReminder(configSlotsReminder);
161     }
162 
163     auto iter = configSlotsReminder.find(slotType);
164     if (iter != configSlotsReminder.end()) {
165         return iter->second->GetReminderFlags();
166     }
167 
168     auto defaultIter = defaultCurrentSlotReminder_.find(slotType);
169     if (defaultIter != defaultCurrentSlotReminder_.end()) {
170         return defaultIter->second;
171     }
172 
173     return 0;
174 }
175 
IsLiveViewEnabled(const std::string bundleName) const176 bool NotificationConfigParse::IsLiveViewEnabled(const std::string bundleName) const
177 {
178     std::shared_ptr<NotificationAppPrivileges> appPrivileges = GetAppPrivileges(bundleName);
179     if (appPrivileges == nullptr) {
180         return false;
181     }
182     return appPrivileges->IsLiveViewEnabled();
183 }
184 
IsReminderEnabled(const std::string & bundleName) const185 bool NotificationConfigParse::IsReminderEnabled(const std::string& bundleName) const
186 {
187     std::shared_ptr<NotificationAppPrivileges> appPrivileges = GetAppPrivileges(bundleName);
188     if (appPrivileges == nullptr) {
189         return false;
190     }
191     return appPrivileges->IsReminderEnabled();
192 }
193 
IsBannerEnabled(const std::string bundleName) const194 bool NotificationConfigParse::IsBannerEnabled(const std::string bundleName) const
195 {
196     std::shared_ptr<NotificationAppPrivileges> appPrivileges = GetAppPrivileges(bundleName);
197     if (appPrivileges != nullptr && appPrivileges->IsBannerEnabled()) {
198         return true;
199     }
200 #ifdef ENABLE_ANS_ADDITIONAL_CONTROL
201     int32_t ctrlResult = EXTENTION_WRAPPER->BannerControl(bundleName);
202     return (ctrlResult == ERR_OK) ? true : false;
203 #else
204     return false;
205 #endif
206 }
207 
GetFlowCtrlConfigFromCCM(FlowControlThreshold & threshold)208 void NotificationConfigParse::GetFlowCtrlConfigFromCCM(FlowControlThreshold &threshold)
209 {
210     nlohmann::json root;
211     std::string JsonPoint = "/";
212     JsonPoint.append(CFG_KEY_NOTIFICATION_SERVICE);
213     if (!GetConfigJson(JsonPoint, root)) {
214         ANS_LOGE("Failed to get JsonPoint CCM config file");
215         return;
216     }
217     if (!root.contains(CFG_KEY_NOTIFICATION_SERVICE)) {
218         ANS_LOGW("GetFlowCtrlConfigFromCCM not found jsonKey");
219         return;
220     }
221     nlohmann::json affects = root[CFG_KEY_NOTIFICATION_SERVICE];
222     if (affects.is_null() || affects.empty()) {
223         ANS_LOGE("GetFlowCtrlConfigFromCCM failed as invalid ccmFlowCtrlConfig json");
224         return;
225     }
226     if (affects.contains(CFG_KEY_MAX_CREATE_NUM_PERSECOND)) {
227         threshold.maxCreateNumPerSecond = affects[CFG_KEY_MAX_CREATE_NUM_PERSECOND];
228     }
229 
230     if (affects.contains(CFG_KEY_MAX_UPDATE_NUM_PERSECOND)) {
231         threshold.maxUpdateNumPerSecond = affects[CFG_KEY_MAX_UPDATE_NUM_PERSECOND];
232     }
233 
234     if (affects.contains(CFG_KEY_MAX_CREATE_NUM_PERSECOND_PERAPP)) {
235         threshold.maxCreateNumPerSecondPerApp = affects[CFG_KEY_MAX_CREATE_NUM_PERSECOND_PERAPP];
236     }
237 
238     if (affects.contains(CFG_KEY_MAX_UPDATE_NUM_PERSECOND_PERAPP)) {
239         threshold.maxUpdateNumPerSecondPerApp = affects[CFG_KEY_MAX_UPDATE_NUM_PERSECOND_PERAPP];
240     }
241 
242     ANS_LOGI("GetFlowCtrlConfigFromCCM success");
243 }
244 
GetSmartReminderEnableList(std::vector<std::string> & deviceTypes)245 bool NotificationConfigParse::GetSmartReminderEnableList(std::vector<std::string>& deviceTypes)
246 {
247     nlohmann::json root;
248     std::string jsonPoint = "/";
249     jsonPoint.append(CFG_KEY_NOTIFICATION_SERVICE);
250     jsonPoint.append("/");
251     jsonPoint.append(CFG_KEY_SMART_REMINDER_ENABLE_LIST);
252     if (!GetConfigJson(jsonPoint, root)) {
253         ANS_LOGE("get configJson fail");
254         return false;
255     }
256 
257     if (root.find(CFG_KEY_NOTIFICATION_SERVICE) == root.end()) {
258         ANS_LOGE("find notificationService fail");
259         return false;
260     }
261 
262     nlohmann::json smartReminderEnableList = root[CFG_KEY_NOTIFICATION_SERVICE][CFG_KEY_SMART_REMINDER_ENABLE_LIST];
263     if (smartReminderEnableList.is_null() || !smartReminderEnableList.is_array() || smartReminderEnableList.empty()) {
264         ANS_LOGE("smartReminderEnableList is invalid");
265         return false;
266     }
267     std::lock_guard<std::mutex> lock(mutex_);
268     deviceTypes = smartReminderEnableList.get<std::vector<std::string>>();
269     return true;
270 }
271 
GetMirrorNotificationEnabledStatus(std::vector<std::string> & deviceTypes)272 bool NotificationConfigParse::GetMirrorNotificationEnabledStatus(std::vector<std::string>& deviceTypes)
273 {
274     nlohmann::json root;
275     std::string jsonPoint = "/";
276     jsonPoint.append(CFG_KEY_NOTIFICATION_SERVICE);
277     jsonPoint.append("/");
278     jsonPoint.append(CFG_KEY_MIRROR_NOTIFICAITON_ENABLED_STATUS);
279     if (!GetConfigJson(jsonPoint, root)) {
280         ANS_LOGE("get configJson fail");
281         return false;
282     }
283 
284     if (root.find(CFG_KEY_NOTIFICATION_SERVICE) == root.end()) {
285         ANS_LOGE("find notificationService fail");
286         return false;
287     }
288 
289     nlohmann::json mirrorNotificationEnabledStatus =
290         root[CFG_KEY_NOTIFICATION_SERVICE][CFG_KEY_MIRROR_NOTIFICAITON_ENABLED_STATUS];
291     if (mirrorNotificationEnabledStatus.is_null() || !mirrorNotificationEnabledStatus.is_array() ||
292         mirrorNotificationEnabledStatus.empty()) {
293         ANS_LOGE("mirrorNotificationEnabledStatus is invalid");
294         return false;
295     }
296     std::lock_guard<std::mutex> lock(mutex_);
297     deviceTypes = mirrorNotificationEnabledStatus.get<std::vector<std::string>>();
298     return true;
299 }
300 
GetAppAndDeviceRelationMap(std::map<std::string,std::string> & relationMap)301 bool NotificationConfigParse::GetAppAndDeviceRelationMap(std::map<std::string, std::string>& relationMap)
302 {
303     nlohmann::json root;
304     std::string jsonPoint = "/";
305     jsonPoint.append(CFG_KEY_NOTIFICATION_SERVICE);
306     jsonPoint.append("/");
307     jsonPoint.append(CFG_KEY_APP_AND_DEVICE_RELATION_MAP);
308     if (!GetConfigJson(jsonPoint, root)) {
309         ANS_LOGE("get configJson fail");
310         return false;
311     }
312 
313     if (root.find(CFG_KEY_NOTIFICATION_SERVICE) == root.end()) {
314         ANS_LOGE("find notificationService fail");
315         return false;
316     }
317 
318     nlohmann::json appAndDeviceRelationMap = root[CFG_KEY_NOTIFICATION_SERVICE][CFG_KEY_APP_AND_DEVICE_RELATION_MAP];
319     if (appAndDeviceRelationMap.is_null() || appAndDeviceRelationMap.empty()) {
320         ANS_LOGE("appAndDeviceRelationMap is invalid");
321         return false;
322     }
323     std::lock_guard<std::mutex> lock(mutex_);
324     for (auto& appAndDeviceRelation : appAndDeviceRelationMap.items()) {
325         relationMap[appAndDeviceRelation.key()] = appAndDeviceRelation.value();
326     }
327     return true;
328 }
329 
GetCollaborativeDeleteType() const330 std::unordered_set<std::string> NotificationConfigParse::GetCollaborativeDeleteType() const
331 {
332     nlohmann::json root;
333     std::string JsonPoint = "/";
334     JsonPoint.append(CFG_KEY_NOTIFICATION_SERVICE);
335     JsonPoint.append("/");
336     JsonPoint.append(CFG_KEY_COLLABORATIVE_DELETE_TYPES);
337     if (!GetConfigJson(JsonPoint, root)) {
338         ANS_LOGE("GetConfigJson faild");
339         return std::unordered_set<std::string>();
340     }
341     if (root.find(CFG_KEY_NOTIFICATION_SERVICE) == root.end()) {
342         ANS_LOGE("appPrivileges null");
343         return std::unordered_set<std::string>();
344     }
345 
346     nlohmann::json collaborativeDeleteTypes = root[CFG_KEY_NOTIFICATION_SERVICE][CFG_KEY_COLLABORATIVE_DELETE_TYPES];
347     if (collaborativeDeleteTypes.empty() && !collaborativeDeleteTypes.is_array()) {
348         ANS_LOGE("collaborativeDeleteTypes null or no array");
349         return std::unordered_set<std::string>();
350     }
351     std::unordered_set<std::string> collaborativeDeleteTypeSet;
352     for (const auto &item : collaborativeDeleteTypes) {
353         if (item.is_string()) {
354             collaborativeDeleteTypeSet.insert(item.get<std::string>());
355         }
356     }
357 
358     return collaborativeDeleteTypeSet;
359 }
360 
GetFilterUidAndBundleName(const std::string & key)361 bool NotificationConfigParse::GetFilterUidAndBundleName(const std::string &key)
362 {
363     nlohmann::json root;
364     std::string jsonPoint = "/";
365     jsonPoint.append(CFG_KEY_NOTIFICATION_SERVICE).append("/").append(COLLABORATION_FILTER).append("/").append(key);
366     if (!GetConfigJson(jsonPoint, root)) {
367         ANS_LOGE("Failed to get jsonPoint CCM config file.");
368         return false;
369     }
370 
371     if (!root.contains(CFG_KEY_NOTIFICATION_SERVICE) ||
372         !root[CFG_KEY_NOTIFICATION_SERVICE].contains(COLLABORATION_FILTER)) {
373         ANS_LOGE("Not found jsonKey collaborationFilter.");
374         return false;
375     }
376 
377     nlohmann::json collaborationFilter = root[CFG_KEY_NOTIFICATION_SERVICE][COLLABORATION_FILTER];
378     if (collaborationFilter.is_null() || collaborationFilter.empty()) {
379         ANS_LOGE("GetCollaborationFilter failed as invalid ccmCollaborationFilter json.");
380         return false;
381     }
382     if (collaborationFilter.contains(key) && collaborationFilter[key].is_array()) {
383         for (const auto& item : collaborationFilter[key]) {
384             if (item.is_number_integer()) {
385                 uidList_.push_back(item.get<int32_t>());
386             }
387             if (item.is_string()) {
388                 bundleNameList_.push_back(item.get<std::string>());
389             }
390         }
391         return true;
392     }
393     return false;
394 }
395 
GetCollaborationFilter()396 void NotificationConfigParse::GetCollaborationFilter()
397 {
398     if (!GetFilterUidAndBundleName(COLLABORATION_FILTER_KEY_UID)) {
399         ANS_LOGW("Failed to get filterUid.");
400     }
401     if (!GetFilterUidAndBundleName(COLLABORATION_FILTER_KEY_NAME)) {
402         ANS_LOGW("Failed to get filterBundleName.");
403     }
404 }
405 
IsInCollaborationFilter(const std::string & bundleName,int32_t uid) const406 bool NotificationConfigParse::IsInCollaborationFilter(const std::string& bundleName, int32_t uid) const
407 {
408     if (uidList_.empty() && bundleNameList_.empty()) {
409         ANS_LOGW("UidList and bundleNameList empty.");
410         return false;
411     }
412 
413     if (std::find(uidList_.begin(), uidList_.end(), uid) != uidList_.end()) {
414         ANS_LOGI("Uid <%{public}d> in CollaborationFilter.", uid);
415         return true;
416     }
417 
418     if (std::find(bundleNameList_.begin(), bundleNameList_.end(), bundleName) != bundleNameList_.end()) {
419         ANS_LOGI("BundleName <%{public}s> in CollaborationFilter.", bundleName.c_str());
420         return true;
421     }
422 
423     ANS_LOGI("Uid <%{public}d> and BundleName <%{public}s> not in CollaborationFilter.", uid, bundleName.c_str());
424     return false;
425 }
426 
GetStartAbilityTimeout()427 uint32_t NotificationConfigParse::GetStartAbilityTimeout()
428 {
429     nlohmann::json root;
430     std::string JsonPoint = "/";
431     JsonPoint.append(CFG_KEY_NOTIFICATION_SERVICE);
432     if (!GetConfigJson(JsonPoint, root)) {
433         ANS_LOGE("Failed to get JsonPoint CCM config file");
434         return 0;
435     }
436     if (!root.contains(CFG_KEY_NOTIFICATION_SERVICE)) {
437         ANS_LOGW("GetStartAbilityTimeout not found jsonKey");
438         return 0;
439     }
440     nlohmann::json affects = root[CFG_KEY_NOTIFICATION_SERVICE];
441     if (affects.is_null() || affects.empty()) {
442         ANS_LOGE("GetStartAbilityTimeout failed as invalid ccmFlowCtrlConfig json");
443         return 0;
444     }
445     if (affects.contains(CFG_KEY_START_ABILITY_TIMEOUT)) {
446         return affects[CFG_KEY_START_ABILITY_TIMEOUT];
447     }
448 
449     return 0;
450 }
451 
GetReportTrustListConfig()452 void NotificationConfigParse::GetReportTrustListConfig()
453 {
454     nlohmann::json root;
455     std::string reportJsonPoint = "/";
456     reportJsonPoint.append(CFG_KEY_NOTIFICATION_SERVICE);
457     reportJsonPoint.append("/");
458     reportJsonPoint.append(CFG_KEY_DFX_NORMAL_EVENT);
459     if (!GetConfigJson(reportJsonPoint, root)) {
460         return;
461     }
462     if (root.find(CFG_KEY_NOTIFICATION_SERVICE) == root.end()) {
463         ANS_LOGE("Failed to get JsonPoint CCM config file");
464         return;
465     }
466 
467     nlohmann::json reportTrustList = root[CFG_KEY_NOTIFICATION_SERVICE][CFG_KEY_DFX_NORMAL_EVENT];
468     if (reportTrustList.is_null() || reportTrustList.empty() || !reportTrustList.is_array()) {
469         ANS_LOGE("GetReportTrustListConfig failed as invalid dfx_normal_events json.");
470         return;
471     }
472     for (auto &reportTrust : reportTrustList) {
473         reporteTrustSet_.emplace(reportTrust);
474     }
475     return;
476 }
477 
478 
IsReportTrustList(const std::string & bundleName) const479 bool NotificationConfigParse::IsReportTrustList(const std::string& bundleName) const
480 {
481     return reporteTrustSet_.count(bundleName);
482 }
483 
484 } // namespace Notification
485 } // namespace OHOS
486