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 "notification_preferences.h"
17 
18 #include <fstream>
19 #include <memory>
20 #include <mutex>
21 
22 #include "access_token_helper.h"
23 #include "ans_const_define.h"
24 #include "ans_inner_errors.h"
25 #include "ans_log_wrapper.h"
26 #include "ans_permission_def.h"
27 #include "bundle_manager_helper.h"
28 #include "hitrace_meter_adapter.h"
29 #include "nlohmann/json.hpp"
30 #include "os_account_manager_helper.h"
31 #include "notification_analytics_util.h"
32 #include "notification_config_parse.h"
33 
34 namespace OHOS {
35 namespace Notification {
36 namespace {
37 const static std::string KEY_BUNDLE_LABEL = "label_ans_bundle_";
38 }
39 std::mutex NotificationPreferences::instanceMutex_;
40 std::shared_ptr<NotificationPreferences> NotificationPreferences::instance_;
41 
NotificationPreferences()42 NotificationPreferences::NotificationPreferences()
43 {
44     preferncesDB_ = std::make_unique<NotificationPreferencesDatabase>();
45     if (preferncesDB_ == nullptr) {
46         HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_7, EventBranchId::BRANCH_1)
47            .Message("preferncesDB is null.");
48         NotificationAnalyticsUtil::ReportModifyEvent(message);
49     }
50     InitSettingFromDisturbDB();
51 }
52 
GetInstance()53 std::shared_ptr<NotificationPreferences> NotificationPreferences::GetInstance()
54 {
55     if (instance_ == nullptr) {
56         std::lock_guard<std::mutex> lock(instanceMutex_);
57         if (instance_ == nullptr) {
58             auto instance = std::make_shared<NotificationPreferences>();
59             instance_ = instance;
60         }
61     }
62     return instance_;
63 }
64 
AddNotificationSlots(const sptr<NotificationBundleOption> & bundleOption,const std::vector<sptr<NotificationSlot>> & slots)65 ErrCode NotificationPreferences::AddNotificationSlots(
66     const sptr<NotificationBundleOption> &bundleOption, const std::vector<sptr<NotificationSlot>> &slots)
67 {
68     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
69     ANS_LOGD("%{public}s", __FUNCTION__);
70     HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_5, EventBranchId::BRANCH_6)
71         .BundleName(bundleOption == nullptr ? "" : bundleOption->GetBundleName());
72     if (bundleOption == nullptr || bundleOption->GetBundleName().empty() || slots.empty()) {
73         message.Message("Invalid param.");
74         NotificationAnalyticsUtil::ReportModifyEvent(message);
75         return ERR_ANS_INVALID_PARAM;
76     }
77     std::lock_guard<std::mutex> lock(preferenceMutex_);
78     NotificationPreferencesInfo preferencesInfo = preferencesInfo_;
79     ErrCode result = ERR_OK;
80     for (auto slot : slots) {
81         result = CheckSlotForCreateSlot(bundleOption, slot, preferencesInfo);
82         if (result != ERR_OK) {
83             return result;
84         }
85     }
86 
87     ANS_LOGD("ffrt: add slot to db!");
88     if (result == ERR_OK &&
89         (!preferncesDB_->PutSlotsToDisturbeDB(bundleOption->GetBundleName(), bundleOption->GetUid(), slots))) {
90         message.Message("put slot for to db failed.");
91         NotificationAnalyticsUtil::ReportModifyEvent(message);
92         return ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED;
93     }
94 
95     if (result == ERR_OK) {
96         preferencesInfo_ = preferencesInfo;
97     }
98     return result;
99 }
100 
AddNotificationBundleProperty(const sptr<NotificationBundleOption> & bundleOption)101 ErrCode NotificationPreferences::AddNotificationBundleProperty(const sptr<NotificationBundleOption> &bundleOption)
102 {
103     if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) {
104         return ERR_ANS_INVALID_PARAM;
105     }
106     std::lock_guard<std::mutex> lock(preferenceMutex_);
107     NotificationPreferencesInfo preferencesInfo = preferencesInfo_;
108     NotificationPreferencesInfo::BundleInfo bundleInfo;
109     preferencesInfo.SetBundleInfo(bundleInfo);
110     ErrCode result = ERR_OK;
111     if (preferncesDB_->PutBundlePropertyToDisturbeDB(bundleInfo)) {
112         preferencesInfo_ = preferencesInfo;
113     } else {
114         result = ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED;
115     }
116     ANS_LOGD("AddNotificationBundleProperty.result: %{public}d", result);
117     return result;
118 }
119 
RemoveNotificationSlot(const sptr<NotificationBundleOption> & bundleOption,const NotificationConstant::SlotType & slotType)120 ErrCode NotificationPreferences::RemoveNotificationSlot(
121     const sptr<NotificationBundleOption> &bundleOption, const NotificationConstant::SlotType &slotType)
122 {
123     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
124     ANS_LOGD("%{public}s", __FUNCTION__);
125     if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) {
126         return ERR_ANS_INVALID_PARAM;
127     }
128     HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_5, EventBranchId::BRANCH_5);
129     message.Message(bundleOption->GetBundleName() + "_" +std::to_string(bundleOption->GetUid()) +
130         " slotType: " + std::to_string(static_cast<uint32_t>(slotType)));
131     message.SlotType(static_cast<uint32_t>(slotType));
132     std::lock_guard<std::mutex> lock(preferenceMutex_);
133     NotificationPreferencesInfo preferencesInfo = preferencesInfo_;
134     ErrCode result = ERR_OK;
135     result = CheckSlotForRemoveSlot(bundleOption, slotType, preferencesInfo);
136     if (result == ERR_OK &&
137         (!preferncesDB_->RemoveSlotFromDisturbeDB(GenerateBundleKey(bundleOption), slotType, bundleOption->GetUid()))) {
138         message.ErrorCode(result).Append(" Remove slot failed.");
139         NotificationAnalyticsUtil::ReportModifyEvent(message);
140         ANS_LOGE("%{public}s_%{public}d, remove slot failed.",
141             bundleOption->GetBundleName().c_str(), bundleOption->GetUid());
142         return ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED;
143     }
144 
145     if (result == ERR_OK) {
146         preferencesInfo_ = preferencesInfo;
147     }
148     ANS_LOGI("%{public}s_%{public}d, Remove slot successful.",
149         bundleOption->GetBundleName().c_str(), bundleOption->GetUid());
150     return result;
151 }
152 
RemoveNotificationAllSlots(const sptr<NotificationBundleOption> & bundleOption)153 ErrCode NotificationPreferences::RemoveNotificationAllSlots(const sptr<NotificationBundleOption> &bundleOption)
154 {
155     ANS_LOGD("%{public}s", __FUNCTION__);
156     if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) {
157         return ERR_ANS_INVALID_PARAM;
158     }
159     HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_5, EventBranchId::BRANCH_3);
160     message.Message(bundleOption->GetBundleName() + "_" +std::to_string(bundleOption->GetUid()));
161     std::lock_guard<std::mutex> lock(preferenceMutex_);
162     NotificationPreferencesInfo preferencesInfo = preferencesInfo_;
163     ErrCode result = ERR_OK;
164     NotificationPreferencesInfo::BundleInfo bundleInfo;
165     if (GetBundleInfo(preferencesInfo, bundleOption, bundleInfo)) {
166         bundleInfo.RemoveAllSlots();
167         preferencesInfo.SetBundleInfo(bundleInfo);
168         if (!preferncesDB_->RemoveAllSlotsFromDisturbeDB(GenerateBundleKey(bundleOption), bundleOption->GetUid())) {
169             result = ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED;
170             message.ErrorCode(result).Append(" Db operation failed.");
171             ANS_LOGE("%{public}s_%{public}d, Db operation failed.",
172                 bundleOption->GetBundleName().c_str(), bundleOption->GetUid());
173         }
174     } else {
175         result = ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST;
176         message.ErrorCode(result).Append(" Notification bundle not exist.");
177         ANS_LOGE("%{public}s_%{public}d, Notification bundle not exist.",
178             bundleOption->GetBundleName().c_str(), bundleOption->GetUid());
179     }
180 
181     if (result == ERR_OK) {
182         preferencesInfo_ = preferencesInfo;
183         message.ErrorCode(result).Append(" Remove all slot successful.");
184         ANS_LOGI("%{public}s_%{public}d, Remove all slot successful.",
185             bundleOption->GetBundleName().c_str(), bundleOption->GetUid());
186     }
187     NotificationAnalyticsUtil::ReportModifyEvent(message);
188     return result;
189 }
190 
RemoveNotificationForBundle(const sptr<NotificationBundleOption> & bundleOption)191 ErrCode NotificationPreferences::RemoveNotificationForBundle(const sptr<NotificationBundleOption> &bundleOption)
192 {
193     ANS_LOGD("%{public}s", __FUNCTION__);
194     if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) {
195         return ERR_ANS_INVALID_PARAM;
196     }
197     std::lock_guard<std::mutex> lock(preferenceMutex_);
198     NotificationPreferencesInfo preferencesInfo = preferencesInfo_;
199 
200     ErrCode result = ERR_OK;
201     NotificationPreferencesInfo::BundleInfo bundleInfo;
202     if (GetBundleInfo(preferencesInfo, bundleOption, bundleInfo)) {
203         preferencesInfo.RemoveBundleInfo(bundleOption);
204         if (!preferncesDB_->RemoveBundleFromDisturbeDB(GenerateBundleKey(bundleOption), bundleOption->GetUid())) {
205             result = ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED;
206         }
207     } else {
208         result = ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST;
209     }
210 
211     if (result == ERR_OK) {
212         preferencesInfo_ = preferencesInfo;
213     }
214 
215     return result;
216 }
217 
UpdateNotificationSlots(const sptr<NotificationBundleOption> & bundleOption,const std::vector<sptr<NotificationSlot>> & slots)218 ErrCode NotificationPreferences::UpdateNotificationSlots(
219     const sptr<NotificationBundleOption> &bundleOption, const std::vector<sptr<NotificationSlot>> &slots)
220 {
221     ANS_LOGD("%{public}s", __FUNCTION__);
222     if (bundleOption == nullptr || bundleOption->GetBundleName().empty() || slots.empty()) {
223         return ERR_ANS_INVALID_PARAM;
224     }
225     HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_5, EventBranchId::BRANCH_2)
226         .BundleName(bundleOption->GetBundleName());
227     std::lock_guard<std::mutex> lock(preferenceMutex_);
228     NotificationPreferencesInfo preferencesInfo = preferencesInfo_;
229     ErrCode result = ERR_OK;
230     for (auto slotIter : slots) {
231         result = CheckSlotForUpdateSlot(bundleOption, slotIter, preferencesInfo);
232         if (result != ERR_OK) {
233             message.Message("Check slot for update failed." + std::to_string(result));
234             NotificationAnalyticsUtil::ReportModifyEvent(message);
235             return result;
236         }
237     }
238 
239     if ((result == ERR_OK) &&
240         (!preferncesDB_->PutSlotsToDisturbeDB(bundleOption->GetBundleName(), bundleOption->GetUid(), slots))) {
241         message.Message("Update put slot for to db failed.");
242         NotificationAnalyticsUtil::ReportModifyEvent(message);
243         return ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED;
244     }
245 
246     if (result == ERR_OK) {
247         preferencesInfo_ = preferencesInfo;
248     }
249 
250     return result;
251 }
252 
GetNotificationSlot(const sptr<NotificationBundleOption> & bundleOption,const NotificationConstant::SlotType & type,sptr<NotificationSlot> & slot)253 ErrCode NotificationPreferences::GetNotificationSlot(const sptr<NotificationBundleOption> &bundleOption,
254     const NotificationConstant::SlotType &type, sptr<NotificationSlot> &slot)
255 {
256     ANS_LOGD("%{public}s", __FUNCTION__);
257     if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) {
258         return ERR_ANS_INVALID_PARAM;
259     }
260 
261     ErrCode result = ERR_OK;
262     NotificationPreferencesInfo::BundleInfo bundleInfo;
263     std::lock_guard<std::mutex> lock(preferenceMutex_);
264     if (GetBundleInfo(preferencesInfo_, bundleOption, bundleInfo)) {
265         if (!bundleInfo.GetSlot(type, slot)) {
266             result = ERR_ANS_PREFERENCES_NOTIFICATION_SLOT_TYPE_NOT_EXIST;
267         }
268     } else {
269         ANS_LOGW("bundle not exist");
270         result = ERR_ANS_PREFERENCES_NOTIFICATION_SLOT_TYPE_NOT_EXIST;
271     }
272     ANS_LOGD("%{public}s status  = %{public}d ", __FUNCTION__, result);
273     return result;
274 }
275 
GetNotificationAllSlots(const sptr<NotificationBundleOption> & bundleOption,std::vector<sptr<NotificationSlot>> & slots)276 ErrCode NotificationPreferences::GetNotificationAllSlots(
277     const sptr<NotificationBundleOption> &bundleOption, std::vector<sptr<NotificationSlot>> &slots)
278 {
279     if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) {
280         return ERR_ANS_INVALID_PARAM;
281     }
282 
283     ErrCode result = ERR_OK;
284     NotificationPreferencesInfo::BundleInfo bundleInfo;
285     std::lock_guard<std::mutex> lock(preferenceMutex_);
286     if (GetBundleInfo(preferencesInfo_, bundleOption, bundleInfo)) {
287         bundleInfo.GetAllSlots(slots);
288     } else {
289         ANS_LOGW("Notification bundle does not exsit.");
290         result = ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST;
291     }
292 
293     return result;
294 }
295 
GetNotificationSlotsNumForBundle(const sptr<NotificationBundleOption> & bundleOption,uint64_t & num)296 ErrCode NotificationPreferences::GetNotificationSlotsNumForBundle(
297     const sptr<NotificationBundleOption> &bundleOption, uint64_t &num)
298 {
299     if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) {
300         return ERR_ANS_INVALID_PARAM;
301     }
302 
303     ErrCode result = ERR_OK;
304     NotificationPreferencesInfo::BundleInfo bundleInfo;
305     std::lock_guard<std::mutex> lock(preferenceMutex_);
306     if (GetBundleInfo(preferencesInfo_, bundleOption, bundleInfo)) {
307         num = static_cast<uint64_t>(bundleInfo.GetAllSlotsSize());
308     } else {
309         result = ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST;
310     }
311     return result;
312 }
313 
GetNotificationSlotFlagsForBundle(const sptr<NotificationBundleOption> & bundleOption,uint32_t & slotFlags)314 ErrCode NotificationPreferences::GetNotificationSlotFlagsForBundle(
315     const sptr<NotificationBundleOption> &bundleOption, uint32_t &slotFlags)
316 {
317     if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) {
318         return ERR_ANS_INVALID_PARAM;
319     }
320 
321     return GetBundleProperty(bundleOption, BundleType::BUNDLE_SLOTFLGS_TYPE, slotFlags);
322 }
323 
IsNotificationSlotFlagsExists(const sptr<NotificationBundleOption> & bundleOption)324 bool NotificationPreferences::IsNotificationSlotFlagsExists(
325     const sptr<NotificationBundleOption> &bundleOption)
326 {
327     if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) {
328         return false;
329     }
330     return preferncesDB_->IsNotificationSlotFlagsExists(bundleOption);
331 }
332 
SetNotificationSlotFlagsForBundle(const sptr<NotificationBundleOption> & bundleOption,uint32_t slotFlags)333 ErrCode NotificationPreferences::SetNotificationSlotFlagsForBundle(
334     const sptr<NotificationBundleOption> &bundleOption, uint32_t slotFlags)
335 {
336     if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) {
337         return ERR_ANS_INVALID_PARAM;
338     }
339 
340     std::lock_guard<std::mutex> lock(preferenceMutex_);
341     NotificationPreferencesInfo preferencesInfo = preferencesInfo_;
342     ErrCode result = SetBundleProperty(preferencesInfo, bundleOption, BundleType::BUNDLE_SLOTFLGS_TYPE, slotFlags);
343     if (result == ERR_OK) {
344         preferencesInfo_ = preferencesInfo;
345     }
346     return result;
347 }
348 
IsShowBadge(const sptr<NotificationBundleOption> & bundleOption,bool & enable)349 ErrCode NotificationPreferences::IsShowBadge(const sptr<NotificationBundleOption> &bundleOption, bool &enable)
350 {
351     if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) {
352         return ERR_ANS_INVALID_PARAM;
353     }
354     return GetBundleProperty(bundleOption, BundleType::BUNDLE_SHOW_BADGE_TYPE, enable);
355 }
356 
SetShowBadge(const sptr<NotificationBundleOption> & bundleOption,const bool enable)357 ErrCode NotificationPreferences::SetShowBadge(const sptr<NotificationBundleOption> &bundleOption, const bool enable)
358 {
359     if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) {
360         return ERR_ANS_INVALID_PARAM;
361     }
362     std::lock_guard<std::mutex> lock(preferenceMutex_);
363     NotificationPreferencesInfo preferencesInfo = preferencesInfo_;
364     ErrCode result = SetBundleProperty(preferencesInfo, bundleOption, BundleType::BUNDLE_SHOW_BADGE_TYPE, enable);
365     if (result == ERR_OK) {
366         preferencesInfo_ = preferencesInfo;
367     }
368     return result;
369 }
370 
GetImportance(const sptr<NotificationBundleOption> & bundleOption,int32_t & importance)371 ErrCode NotificationPreferences::GetImportance(const sptr<NotificationBundleOption> &bundleOption, int32_t &importance)
372 {
373     if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) {
374         return ERR_ANS_INVALID_PARAM;
375     }
376 
377     return GetBundleProperty(bundleOption, BundleType::BUNDLE_IMPORTANCE_TYPE, importance);
378 }
379 
380 
SetImportance(const sptr<NotificationBundleOption> & bundleOption,const int32_t & importance)381 ErrCode NotificationPreferences::SetImportance(
382     const sptr<NotificationBundleOption> &bundleOption, const int32_t &importance)
383 {
384     if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) {
385         return ERR_ANS_INVALID_PARAM;
386     }
387     std::lock_guard<std::mutex> lock(preferenceMutex_);
388     NotificationPreferencesInfo preferencesInfo = preferencesInfo_;
389     ErrCode result = SetBundleProperty(preferencesInfo, bundleOption, BundleType::BUNDLE_IMPORTANCE_TYPE, importance);
390     if (result == ERR_OK) {
391         preferencesInfo_ = preferencesInfo;
392     }
393     return result;
394 }
395 
GetTotalBadgeNums(const sptr<NotificationBundleOption> & bundleOption,int32_t & totalBadgeNum)396 ErrCode NotificationPreferences::GetTotalBadgeNums(
397     const sptr<NotificationBundleOption> &bundleOption, int32_t &totalBadgeNum)
398 {
399     if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) {
400         return ERR_ANS_INVALID_PARAM;
401     }
402     return GetBundleProperty(bundleOption, BundleType::BUNDLE_BADGE_TOTAL_NUM_TYPE, totalBadgeNum);
403 }
404 
SetTotalBadgeNums(const sptr<NotificationBundleOption> & bundleOption,const int32_t num)405 ErrCode NotificationPreferences::SetTotalBadgeNums(
406     const sptr<NotificationBundleOption> &bundleOption, const int32_t num)
407 {
408     if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) {
409         return ERR_ANS_INVALID_PARAM;
410     }
411     std::lock_guard<std::mutex> lock(preferenceMutex_);
412     NotificationPreferencesInfo preferencesInfo = preferencesInfo_;
413     ErrCode result = SetBundleProperty(preferencesInfo, bundleOption, BundleType::BUNDLE_BADGE_TOTAL_NUM_TYPE, num);
414     if (result == ERR_OK) {
415         preferencesInfo_ = preferencesInfo;
416     }
417     return result;
418 }
419 
GetNotificationsEnabledForBundle(const sptr<NotificationBundleOption> & bundleOption,bool & enabled)420 ErrCode NotificationPreferences::GetNotificationsEnabledForBundle(
421     const sptr<NotificationBundleOption> &bundleOption, bool &enabled)
422 {
423     if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) {
424         return ERR_ANS_INVALID_PARAM;
425     }
426     return GetBundleProperty(bundleOption, BundleType::BUNDLE_ENABLE_NOTIFICATION_TYPE, enabled);
427 }
428 
SetNotificationsEnabledForBundle(const sptr<NotificationBundleOption> & bundleOption,const bool enabled)429 ErrCode NotificationPreferences::SetNotificationsEnabledForBundle(
430     const sptr<NotificationBundleOption> &bundleOption, const bool enabled)
431 {
432     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
433     if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) {
434         return ERR_ANS_INVALID_PARAM;
435     }
436 
437     std::lock_guard<std::mutex> lock(preferenceMutex_);
438     NotificationPreferencesInfo preferencesInfo = preferencesInfo_;
439     ErrCode result =
440         SetBundleProperty(preferencesInfo, bundleOption, BundleType::BUNDLE_ENABLE_NOTIFICATION_TYPE, enabled);
441     if (result == ERR_OK) {
442         preferencesInfo_ = preferencesInfo;
443     }
444     return result;
445 }
446 
GetNotificationsEnabled(const int32_t & userId,bool & enabled)447 ErrCode NotificationPreferences::GetNotificationsEnabled(const int32_t &userId, bool &enabled)
448 {
449     if (userId <= SUBSCRIBE_USER_INIT) {
450         return ERR_ANS_INVALID_PARAM;
451     }
452 
453     ErrCode result = ERR_OK;
454     std::lock_guard<std::mutex> lock(preferenceMutex_);
455     if (!preferencesInfo_.GetEnabledAllNotification(userId, enabled)) {
456         result = ERR_ANS_INVALID_PARAM;
457     }
458     return result;
459 }
460 
SetNotificationsEnabled(const int32_t & userId,const bool & enabled)461 ErrCode NotificationPreferences::SetNotificationsEnabled(const int32_t &userId, const bool &enabled)
462 {
463     if (userId <= SUBSCRIBE_USER_INIT) {
464         return ERR_ANS_INVALID_PARAM;
465     }
466     std::lock_guard<std::mutex> lock(preferenceMutex_);
467     NotificationPreferencesInfo preferencesInfo = preferencesInfo_;
468     preferencesInfo.SetEnabledAllNotification(userId, enabled);
469     ErrCode result = ERR_OK;
470     if (!preferncesDB_->PutNotificationsEnabled(userId, enabled)) {
471         result = ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED;
472     }
473 
474     if (result == ERR_OK) {
475         preferencesInfo_ = preferencesInfo;
476     }
477     return result;
478 }
479 
GetHasPoppedDialog(const sptr<NotificationBundleOption> & bundleOption,bool & hasPopped)480 ErrCode NotificationPreferences::GetHasPoppedDialog(const sptr<NotificationBundleOption> &bundleOption, bool &hasPopped)
481 {
482     if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) {
483         return ERR_ANS_INVALID_PARAM;
484     }
485     return GetBundleProperty(bundleOption, BundleType::BUNDLE_POPPED_DIALOG_TYPE, hasPopped);
486 }
487 
SetHasPoppedDialog(const sptr<NotificationBundleOption> & bundleOption,bool hasPopped)488 ErrCode NotificationPreferences::SetHasPoppedDialog(const sptr<NotificationBundleOption> &bundleOption, bool hasPopped)
489 {
490     if (bundleOption == nullptr) {
491         return ERR_ANS_INVALID_PARAM;
492     }
493     std::lock_guard<std::mutex> lock(preferenceMutex_);
494     NotificationPreferencesInfo preferencesInfo = preferencesInfo_;
495     ErrCode result = ERR_OK;
496     result = SetBundleProperty(preferencesInfo, bundleOption, BundleType::BUNDLE_POPPED_DIALOG_TYPE, hasPopped);
497     if (result == ERR_OK) {
498         preferencesInfo_ = preferencesInfo;
499     }
500     return result;
501 }
502 
GetDoNotDisturbDate(const int32_t & userId,sptr<NotificationDoNotDisturbDate> & date)503 ErrCode NotificationPreferences::GetDoNotDisturbDate(const int32_t &userId,
504     sptr<NotificationDoNotDisturbDate> &date)
505 {
506     if (userId <= SUBSCRIBE_USER_INIT) {
507         return ERR_ANS_INVALID_PARAM;
508     }
509 
510     ErrCode result = ERR_OK;
511     std::lock_guard<std::mutex> lock(preferenceMutex_);
512     NotificationPreferencesInfo preferencesInfo = preferencesInfo_;
513     if (!preferencesInfo.GetDoNotDisturbDate(userId, date)) {
514         result = ERR_ANS_INVALID_PARAM;
515     }
516     return result;
517 }
518 
SetDoNotDisturbDate(const int32_t & userId,const sptr<NotificationDoNotDisturbDate> date)519 ErrCode NotificationPreferences::SetDoNotDisturbDate(const int32_t &userId,
520     const sptr<NotificationDoNotDisturbDate> date)
521 {
522     ANS_LOGE("enter.");
523     if (userId <= SUBSCRIBE_USER_INIT) {
524         return ERR_ANS_INVALID_PARAM;
525     }
526     std::lock_guard<std::mutex> lock(preferenceMutex_);
527     NotificationPreferencesInfo preferencesInfo = preferencesInfo_;
528     preferencesInfo.SetDoNotDisturbDate(userId, date);
529 
530     ErrCode result = ERR_OK;
531     if (!preferncesDB_->PutDoNotDisturbDate(userId, date)) {
532         result = ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED;
533     }
534 
535     if (result == ERR_OK) {
536         preferencesInfo_ = preferencesInfo;
537     }
538     return result;
539 }
540 
CheckDoNotDisturbProfileID(int32_t profileId)541 bool NotificationPreferences::CheckDoNotDisturbProfileID(int32_t profileId)
542 {
543     if (profileId < DO_NOT_DISTURB_PROFILE_MIN_ID || profileId > DO_NOT_DISTURB_PROFILE_MAX_ID) {
544         ANS_LOGE("The profile id is out of range.");
545         return false;
546     }
547     return true;
548 }
549 
AddDoNotDisturbProfiles(int32_t userId,std::vector<sptr<NotificationDoNotDisturbProfile>> profiles)550 ErrCode NotificationPreferences::AddDoNotDisturbProfiles(
551     int32_t userId, std::vector<sptr<NotificationDoNotDisturbProfile>> profiles)
552 {
553     ANS_LOGD("Called.");
554     for (auto profile : profiles) {
555         if (profile == nullptr) {
556             ANS_LOGE("The profile is nullptr.");
557             return ERR_ANS_INVALID_PARAM;
558         }
559         if (!CheckDoNotDisturbProfileID(profile->GetProfileId())) {
560             return ERR_ANS_INVALID_PARAM;
561         }
562         auto trustList = profile->GetProfileTrustList();
563         for (auto& bundleInfo : trustList) {
564             int32_t index = BundleManagerHelper::GetInstance()->GetAppIndexByUid(bundleInfo.GetUid());
565             bundleInfo.SetAppIndex(index);
566             ANS_LOGI("Get app index by uid %{public}d %{public}s %{public}d", bundleInfo.GetUid(),
567                 bundleInfo.GetBundleName().c_str(), index);
568         }
569         profile->SetProfileTrustList(trustList);
570     }
571     std::lock_guard<std::mutex> lock(preferenceMutex_);
572     NotificationPreferencesInfo preferencesInfo = preferencesInfo_;
573     preferencesInfo.AddDoNotDisturbProfiles(userId, profiles);
574     if (preferncesDB_ == nullptr) {
575         ANS_LOGE("The prefernces db is nullptr.");
576         return ERR_ANS_SERVICE_NOT_READY;
577     }
578     if (!preferncesDB_->AddDoNotDisturbProfiles(userId, profiles)) {
579         return ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED;
580     }
581     preferencesInfo_ = preferencesInfo;
582     return ERR_OK;
583 }
584 
GetBundleInfo(NotificationPreferencesInfo & preferencesInfo,const sptr<NotificationBundleOption> & bundleOption,NotificationPreferencesInfo::BundleInfo & info) const585 bool NotificationPreferences::GetBundleInfo(NotificationPreferencesInfo &preferencesInfo,
586     const sptr<NotificationBundleOption> &bundleOption, NotificationPreferencesInfo::BundleInfo &info) const
587 {
588     if (preferencesInfo.GetBundleInfo(bundleOption, info)) {
589         return true;
590     } else if (preferncesDB_->GetBundleInfo(bundleOption, info)) {
591         preferencesInfo.SetBundleInfo(info);
592         return true;
593     }
594     return false;
595 }
596 
RemoveDoNotDisturbProfiles(int32_t userId,const std::vector<sptr<NotificationDoNotDisturbProfile>> profiles)597 ErrCode NotificationPreferences::RemoveDoNotDisturbProfiles(
598     int32_t userId, const std::vector<sptr<NotificationDoNotDisturbProfile>> profiles)
599 {
600     ANS_LOGD("Called.");
601     for (auto profile : profiles) {
602         if (profile == nullptr) {
603             ANS_LOGE("The profile is nullptr.");
604             return ERR_ANS_INVALID_PARAM;
605         }
606         if (!CheckDoNotDisturbProfileID(profile->GetProfileId())) {
607             return ERR_ANS_INVALID_PARAM;
608         }
609     }
610     std::lock_guard<std::mutex> lock(preferenceMutex_);
611     NotificationPreferencesInfo preferencesInfo = preferencesInfo_;
612     preferencesInfo.RemoveDoNotDisturbProfiles(userId, profiles);
613     if (preferncesDB_ == nullptr) {
614         ANS_LOGE("The prefernces db is nullptr.");
615         return ERR_ANS_SERVICE_NOT_READY;
616     }
617     if (!preferncesDB_->RemoveDoNotDisturbProfiles(userId, profiles)) {
618         return ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED;
619     }
620     preferencesInfo_ = preferencesInfo;
621     return ERR_OK;
622 }
623 
UpdateProfilesUtil(std::vector<NotificationBundleOption> & trustList,const std::vector<NotificationBundleOption> bundleList)624 void NotificationPreferences::UpdateProfilesUtil(std::vector<NotificationBundleOption>& trustList,
625     const std::vector<NotificationBundleOption> bundleList)
626 {
627     for (auto& item : bundleList) {
628         bool exit = false;
629         for (auto& bundle: trustList) {
630             if (item.GetUid() == bundle.GetUid()) {
631                 exit = true;
632                 break;
633             }
634         }
635         if (!exit) {
636             trustList.push_back(item);
637         }
638     }
639 }
640 
UpdateDoNotDisturbProfiles(int32_t userId,int32_t profileId,const std::string & name,const std::vector<NotificationBundleOption> & bundleList)641 ErrCode NotificationPreferences::UpdateDoNotDisturbProfiles(int32_t userId, int32_t profileId,
642     const std::string& name, const std::vector<NotificationBundleOption>& bundleList)
643 {
644     ANS_LOGI("Called update Profile %{public}d %{public}d %{public}zu.", userId, profileId, bundleList.size());
645     if (!CheckDoNotDisturbProfileID(profileId) || bundleList.empty()) {
646         return ERR_ANS_INVALID_PARAM;
647     }
648 
649     sptr<NotificationDoNotDisturbProfile> profile = new (std::nothrow) NotificationDoNotDisturbProfile();
650     std::lock_guard<std::mutex> lock(preferenceMutex_);
651     NotificationPreferencesInfo preferencesInfo = preferencesInfo_;
652     if (preferencesInfo.GetDoNotDisturbProfiles(profileId, userId, profile)) {
653         auto trustList = profile->GetProfileTrustList();
654         UpdateProfilesUtil(trustList, bundleList);
655         profile->SetProfileTrustList(trustList);
656     } else {
657         profile->SetProfileId(profileId);
658         profile->SetProfileName(name);
659         profile->SetProfileTrustList(bundleList);
660     }
661     ANS_LOGI("Update profile %{public}d %{public}d %{public}zu", userId, profile->GetProfileId(),
662         profile->GetProfileTrustList().size());
663     preferencesInfo.AddDoNotDisturbProfiles(userId, {profile});
664     if (preferncesDB_ == nullptr) {
665         ANS_LOGE("The prefernces db is nullptr.");
666         return ERR_ANS_SERVICE_NOT_READY;
667     }
668     if (!preferncesDB_->AddDoNotDisturbProfiles(userId, {profile})) {
669         return ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED;
670     }
671     preferencesInfo_ = preferencesInfo;
672     return ERR_OK;
673 }
674 
UpdateCloneBundleInfo(int32_t userId,const NotificationCloneBundleInfo & cloneBundleInfo)675 void NotificationPreferences::UpdateCloneBundleInfo(int32_t userId,
676     const NotificationCloneBundleInfo& cloneBundleInfo)
677 {
678     ANS_LOGI("Event bundle update %{public}s.", cloneBundleInfo.Dump().c_str());
679     NotificationPreferencesInfo::BundleInfo bundleInfo;
680     sptr<NotificationBundleOption> bundleOption = new NotificationBundleOption();
681     bundleOption->SetBundleName(cloneBundleInfo.GetBundleName());
682     bundleOption->SetUid(cloneBundleInfo.GetUid());
683     std::lock_guard<std::mutex> lock(preferenceMutex_);
684     NotificationPreferencesInfo preferencesInfo = preferencesInfo_;
685     if (!GetBundleInfo(preferencesInfo, bundleOption, bundleInfo)) {
686         bundleInfo.SetBundleName(cloneBundleInfo.GetBundleName());
687         bundleInfo.SetBundleUid(cloneBundleInfo.GetUid());
688     }
689 
690     /* after clone, override these witch */
691     bundleInfo.SetSlotFlags(cloneBundleInfo.GetSlotFlags());
692     bundleInfo.SetIsShowBadge(cloneBundleInfo.GetIsShowBadge());
693     bundleInfo.SetEnableNotification(cloneBundleInfo.GetEnableNotification());
694     /* update property to db */
695     if (!preferncesDB_->UpdateBundlePropertyToDisturbeDB(userId, bundleInfo)) {
696         ANS_LOGW("Clone bundle info failed %{public}s.", cloneBundleInfo.Dump().c_str());
697         return;
698     }
699     preferencesInfo.SetBundleInfo(bundleInfo);
700 
701     /* update slot info */
702     std::vector<sptr<NotificationSlot>> slots;
703     for (auto& cloneSlot : cloneBundleInfo.GetSlotInfo()) {
704         sptr<NotificationSlot> slotInfo = new (std::nothrow) NotificationSlot(cloneSlot.slotType_);
705         uint32_t slotFlags = bundleInfo.GetSlotFlags();
706         auto configSlotReminderMode = DelayedSingleton<NotificationConfigParse>::GetInstance()->
707             GetConfigSlotReminderModeByType(slotInfo->GetType(), bundleOption);
708         slotInfo->SetReminderMode(configSlotReminderMode & slotFlags);
709         slotInfo->SetEnable(cloneSlot.enable_);
710         slotInfo->SetForceControl(cloneSlot.isForceControl_);
711         slotInfo->SetAuthorizedStatus(NotificationSlot::AuthorizedStatus::AUTHORIZED);
712         slots.push_back(slotInfo);
713         bundleInfo.SetSlot(slotInfo);
714     }
715 
716     if (!preferncesDB_->UpdateBundleSlotToDisturbeDB(userId, cloneBundleInfo.GetBundleName(),
717         cloneBundleInfo.GetUid(), slots)) {
718         ANS_LOGW("Clone bundle slot failed %{public}s.", cloneBundleInfo.Dump().c_str());
719         preferencesInfo_ = preferencesInfo;
720         return;
721     }
722     preferencesInfo.SetBundleInfo(bundleInfo);
723     preferencesInfo_ = preferencesInfo;
724 }
725 
GetAllCLoneBundlesInfo(int32_t userId,std::vector<NotificationCloneBundleInfo> & cloneBundles)726 void NotificationPreferences::GetAllCLoneBundlesInfo(int32_t userId,
727     std::vector<NotificationCloneBundleInfo> &cloneBundles)
728 {
729     std::lock_guard<std::mutex> lock(preferenceMutex_);
730     NotificationPreferencesInfo preferencesInfo = preferencesInfo_;
731     std::unordered_map<std::string, std::string> bundlesMap;
732     if (GetBatchKvsFromDb(KEY_BUNDLE_LABEL, bundlesMap, userId) != ERR_OK) {
733         ANS_LOGE("Get bundle map info failed.");
734         return;
735     }
736     preferencesInfo.GetAllCLoneBundlesInfo(userId, bundlesMap, cloneBundles);
737     preferencesInfo_ = preferencesInfo;
738 }
739 
GetDoNotDisturbProfileListByUserId(int32_t userId,std::vector<sptr<NotificationDoNotDisturbProfile>> & profiles)740 void NotificationPreferences::GetDoNotDisturbProfileListByUserId(int32_t userId,
741     std::vector<sptr<NotificationDoNotDisturbProfile>> &profiles)
742 {
743     std::lock_guard<std::mutex> lock(preferenceMutex_);
744     preferencesInfo_.GetAllDoNotDisturbProfiles(userId, profiles);
745 }
746 
GetAllNotificationEnabledBundles(std::vector<NotificationBundleOption> & bundleOption)747 ErrCode NotificationPreferences::GetAllNotificationEnabledBundles(std::vector<NotificationBundleOption> &bundleOption)
748 {
749     ANS_LOGD("Called.");
750     std::lock_guard<std::mutex> lock(preferenceMutex_);
751     if (preferncesDB_ == nullptr) {
752         return ERR_ANS_SERVICE_NOT_READY;
753     }
754     if (!preferncesDB_->GetAllNotificationEnabledBundles(bundleOption)) {
755         return ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED;
756     }
757     return ERR_OK;
758 }
759 
ClearNotificationInRestoreFactorySettings()760 ErrCode NotificationPreferences::ClearNotificationInRestoreFactorySettings()
761 {
762     ErrCode result = ERR_OK;
763     std::lock_guard<std::mutex> lock(preferenceMutex_);
764     if (!preferncesDB_->RemoveAllDataFromDisturbeDB()) {
765         result = ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED;
766     }
767 
768     if (result == ERR_OK) {
769         preferencesInfo_ = NotificationPreferencesInfo();
770     }
771     return result;
772 }
773 
GetDoNotDisturbProfile(int32_t profileId,int32_t userId,sptr<NotificationDoNotDisturbProfile> & profile)774 ErrCode NotificationPreferences::GetDoNotDisturbProfile(
775     int32_t profileId, int32_t userId, sptr<NotificationDoNotDisturbProfile> &profile)
776 {
777     if (!CheckDoNotDisturbProfileID(profileId)) {
778         return ERR_ANS_INVALID_PARAM;
779     }
780     std::lock_guard<std::mutex> lock(preferenceMutex_);
781     if (!preferencesInfo_.GetDoNotDisturbProfiles(profileId, userId, profile)) {
782         return ERR_ANS_NO_PROFILE_TEMPLATE;
783     }
784     return ERR_OK;
785 }
786 
RemoveDoNotDisturbProfileTrustList(int32_t userId,const sptr<NotificationBundleOption> & bundleOption)787 void NotificationPreferences::RemoveDoNotDisturbProfileTrustList(
788     int32_t userId, const sptr<NotificationBundleOption> &bundleOption)
789 {
790     if (bundleOption == nullptr) {
791         ANS_LOGE("The bundle option is nullptr.");
792         return;
793     }
794     int32_t uid = bundleOption->GetUid();
795     int32_t appIndex = bundleOption->GetAppIndex();
796     auto bundleName = bundleOption->GetBundleName();
797     ANS_LOGI("Remove %{public}s %{public}d %{public}d.", bundleName.c_str(), uid, appIndex);
798     std::lock_guard<std::mutex> lock(preferenceMutex_);
799     NotificationPreferencesInfo preferencesInfo = preferencesInfo_;
800 
801     std::vector<sptr<NotificationDoNotDisturbProfile>> profiles;
802     preferencesInfo.GetAllDoNotDisturbProfiles(userId, profiles);
803     for (auto profile : profiles) {
804         if (profile == nullptr) {
805             ANS_LOGE("The profile is nullptr.");
806             continue;
807         }
808         auto trustList = profile->GetProfileTrustList();
809         for (auto it = trustList.begin(); it != trustList.end(); it++) {
810             if (it->GetUid() == uid) {
811                 trustList.erase(it);
812                 break;
813             }
814         }
815         profile->SetProfileTrustList(trustList);
816     }
817     preferencesInfo.AddDoNotDisturbProfiles(userId, profiles);
818     if (preferncesDB_ == nullptr) {
819         ANS_LOGE("The prefernces db is nullptr.");
820         return;
821     }
822     if (!preferncesDB_->AddDoNotDisturbProfiles(userId, profiles)) {
823         return;
824     }
825     preferencesInfo_ = preferencesInfo;
826 }
827 
CheckSlotForCreateSlot(const sptr<NotificationBundleOption> & bundleOption,const sptr<NotificationSlot> & slot,NotificationPreferencesInfo & preferencesInfo) const828 ErrCode NotificationPreferences::CheckSlotForCreateSlot(const sptr<NotificationBundleOption> &bundleOption,
829     const sptr<NotificationSlot> &slot, NotificationPreferencesInfo &preferencesInfo) const
830 {
831     if (slot == nullptr) {
832         ANS_LOGE("Notification slot is nullptr.");
833         return ERR_ANS_PREFERENCES_NOTIFICATION_SLOT_NOT_EXIST;
834     }
835 
836     NotificationPreferencesInfo::BundleInfo bundleInfo;
837     if (!GetBundleInfo(preferencesInfo, bundleOption, bundleInfo)) {
838         bundleInfo.SetBundleName(bundleOption->GetBundleName());
839         bundleInfo.SetBundleUid(bundleOption->GetUid());
840         bundleInfo.SetEnableNotification(CheckApiCompatibility(bundleOption));
841     }
842     bundleInfo.SetSlot(slot);
843     preferencesInfo.SetBundleInfo(bundleInfo);
844 
845     return ERR_OK;
846 }
847 
CheckSlotForRemoveSlot(const sptr<NotificationBundleOption> & bundleOption,const NotificationConstant::SlotType & slotType,NotificationPreferencesInfo & preferencesInfo) const848 ErrCode NotificationPreferences::CheckSlotForRemoveSlot(const sptr<NotificationBundleOption> &bundleOption,
849     const NotificationConstant::SlotType &slotType, NotificationPreferencesInfo &preferencesInfo) const
850 {
851     ErrCode result = ERR_OK;
852     NotificationPreferencesInfo::BundleInfo bundleInfo;
853     if (GetBundleInfo(preferencesInfo, bundleOption, bundleInfo)) {
854         if (bundleInfo.IsExsitSlot(slotType)) {
855             bundleInfo.RemoveSlot(slotType);
856             preferencesInfo.SetBundleInfo(bundleInfo);
857         } else {
858             ANS_LOGE("Notification slot type does not exsited.");
859             result = ERR_ANS_PREFERENCES_NOTIFICATION_SLOT_TYPE_NOT_EXIST;
860         }
861     } else {
862         ANS_LOGW("Notification bundle does not exsit.");
863         result = ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST;
864     }
865     return result;
866 }
867 
CheckSlotForUpdateSlot(const sptr<NotificationBundleOption> & bundleOption,const sptr<NotificationSlot> & slot,NotificationPreferencesInfo & preferencesInfo) const868 ErrCode NotificationPreferences::CheckSlotForUpdateSlot(const sptr<NotificationBundleOption> &bundleOption,
869     const sptr<NotificationSlot> &slot, NotificationPreferencesInfo &preferencesInfo) const
870 {
871     if (slot == nullptr) {
872         ANS_LOGE("Notification slot is nullptr.");
873         return ERR_ANS_INVALID_PARAM;
874     }
875 
876     ErrCode result = ERR_OK;
877     NotificationPreferencesInfo::BundleInfo bundleInfo;
878     if (GetBundleInfo(preferencesInfo, bundleOption, bundleInfo)) {
879         if (bundleInfo.IsExsitSlot(slot->GetType())) {
880             bundleInfo.SetBundleName(bundleOption->GetBundleName());
881             bundleInfo.SetBundleUid(bundleOption->GetUid());
882             bundleInfo.SetSlot(slot);
883             preferencesInfo.SetBundleInfo(bundleInfo);
884         } else {
885             ANS_LOGE("Notification slot type does not exist.");
886             result = ERR_ANS_PREFERENCES_NOTIFICATION_SLOT_TYPE_NOT_EXIST;
887         }
888     } else {
889         ANS_LOGW("Notification bundle does not exsit.");
890         result = ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST;
891     }
892 
893     return result;
894 }
895 
896 template <typename T>
SetBundleProperty(NotificationPreferencesInfo & preferencesInfo,const sptr<NotificationBundleOption> & bundleOption,const BundleType & type,const T & value)897 ErrCode NotificationPreferences::SetBundleProperty(NotificationPreferencesInfo &preferencesInfo,
898     const sptr<NotificationBundleOption> &bundleOption, const BundleType &type, const T &value)
899 {
900     ErrCode result = ERR_OK;
901     NotificationPreferencesInfo::BundleInfo bundleInfo;
902     if (!GetBundleInfo(preferencesInfo_, bundleOption, bundleInfo)) {
903         bundleInfo.SetBundleName(bundleOption->GetBundleName());
904         bundleInfo.SetBundleUid(bundleOption->GetUid());
905         bundleInfo.SetEnableNotification(CheckApiCompatibility(bundleOption));
906     }
907     result = SaveBundleProperty(bundleInfo, bundleOption, type, value);
908     if (result == ERR_OK) {
909         preferencesInfo.SetBundleInfo(bundleInfo);
910     }
911 
912     return result;
913 }
914 
915 template <typename T>
SaveBundleProperty(NotificationPreferencesInfo::BundleInfo & bundleInfo,const sptr<NotificationBundleOption> & bundleOption,const BundleType & type,const T & value)916 ErrCode NotificationPreferences::SaveBundleProperty(NotificationPreferencesInfo::BundleInfo &bundleInfo,
917     const sptr<NotificationBundleOption> &bundleOption, const BundleType &type, const T &value)
918 {
919     bool storeDBResult = true;
920     switch (type) {
921         case BundleType::BUNDLE_IMPORTANCE_TYPE:
922             bundleInfo.SetImportance(value);
923             storeDBResult = preferncesDB_->PutImportance(bundleInfo, value);
924             break;
925         case BundleType::BUNDLE_BADGE_TOTAL_NUM_TYPE:
926             bundleInfo.SetBadgeTotalNum(value);
927             storeDBResult = preferncesDB_->PutTotalBadgeNums(bundleInfo, value);
928             break;
929         case BundleType::BUNDLE_SHOW_BADGE_TYPE:
930             bundleInfo.SetIsShowBadge(value);
931             storeDBResult = preferncesDB_->PutShowBadge(bundleInfo, value);
932             break;
933         case BundleType::BUNDLE_ENABLE_NOTIFICATION_TYPE:
934             bundleInfo.SetEnableNotification(value);
935             storeDBResult = preferncesDB_->PutNotificationsEnabledForBundle(bundleInfo, value);
936             break;
937         case BundleType::BUNDLE_POPPED_DIALOG_TYPE:
938             ANS_LOGI("Into BUNDLE_POPPED_DIALOG_TYPE:SetHasPoppedDialog.");
939             bundleInfo.SetHasPoppedDialog(value);
940             storeDBResult = preferncesDB_->PutHasPoppedDialog(bundleInfo, value);
941             break;
942         case BundleType::BUNDLE_SLOTFLGS_TYPE:
943             ANS_LOGI("Into BUNDLE_SLOTFLGS_TYPE:SetSlotFlags.");
944             bundleInfo.SetSlotFlags(value);
945             storeDBResult = preferncesDB_->PutSlotFlags(bundleInfo, value);
946             break;
947         default:
948             break;
949     }
950     return storeDBResult ? ERR_OK : ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED;
951 }
952 
953 template <typename T>
GetBundleProperty(const sptr<NotificationBundleOption> & bundleOption,const BundleType & type,T & value)954 ErrCode NotificationPreferences::GetBundleProperty(
955     const sptr<NotificationBundleOption> &bundleOption, const BundleType &type, T &value)
956 {
957     ErrCode result = ERR_OK;
958     NotificationPreferencesInfo::BundleInfo bundleInfo;
959     std::lock_guard<std::mutex> lock(preferenceMutex_);
960     if (GetBundleInfo(preferencesInfo_, bundleOption, bundleInfo)) {
961         switch (type) {
962             case BundleType::BUNDLE_IMPORTANCE_TYPE:
963                 value = bundleInfo.GetImportance();
964                 break;
965             case BundleType::BUNDLE_BADGE_TOTAL_NUM_TYPE:
966                 value = bundleInfo.GetBadgeTotalNum();
967                 break;
968             case BundleType::BUNDLE_SHOW_BADGE_TYPE:
969                 value = bundleInfo.GetIsShowBadge();
970                 break;
971             case BundleType::BUNDLE_ENABLE_NOTIFICATION_TYPE:
972                 value = bundleInfo.GetEnableNotification();
973                 break;
974             case BundleType::BUNDLE_POPPED_DIALOG_TYPE:
975                 ANS_LOGD("Into BUNDLE_POPPED_DIALOG_TYPE:GetHasPoppedDialog.");
976                 value = bundleInfo.GetHasPoppedDialog();
977                 break;
978             case BundleType::BUNDLE_SLOTFLGS_TYPE:
979                 value = bundleInfo.GetSlotFlags();
980                 ANS_LOGD("Into BUNDLE_SLOTFLGS_TYPE:GetSlotFlags.");
981                 break;
982             default:
983                 result = ERR_ANS_INVALID_PARAM;
984                 break;
985         }
986     } else {
987         ANS_LOGW("Notification bundle does not exsit.");
988         result = ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST;
989     }
990     return result;
991 }
992 
GenerateBundleKey(const sptr<NotificationBundleOption> & bundleOption) const993 std::string NotificationPreferences::GenerateBundleKey(const sptr<NotificationBundleOption> &bundleOption) const
994 {
995     return bundleOption->GetBundleName().append(std::to_string(bundleOption->GetUid()));
996 }
997 
GetTemplateSupported(const std::string & templateName,bool & support)998 ErrCode NotificationPreferences::GetTemplateSupported(const std::string& templateName, bool &support)
999 {
1000     if (templateName.length() == 0) {
1001         ANS_LOGE("template name is null.");
1002         return ERR_ANS_INVALID_PARAM;
1003     }
1004 
1005     std::ifstream inFile;
1006     inFile.open(DEFAULT_TEMPLATE_PATH.c_str(), std::ios::in);
1007     if (!inFile.is_open()) {
1008         ANS_LOGE("read template config error.");
1009         return ERR_ANS_PREFERENCES_NOTIFICATION_READ_TEMPLATE_CONFIG_FAILED;
1010     }
1011 
1012     nlohmann::json jsonObj;
1013     inFile >> jsonObj;
1014     if (jsonObj.is_null() || !jsonObj.is_object()) {
1015         ANS_LOGE("Invalid JSON object");
1016         return ERR_ANS_PREFERENCES_NOTIFICATION_READ_TEMPLATE_CONFIG_FAILED;
1017     }
1018     if (jsonObj.is_discarded()) {
1019         ANS_LOGE("template json discarded error.");
1020         inFile.close();
1021         return ERR_ANS_PREFERENCES_NOTIFICATION_READ_TEMPLATE_CONFIG_FAILED;
1022     }
1023 
1024     if (jsonObj.contains(templateName)) {
1025         support = true;
1026     }
1027 
1028     jsonObj.clear();
1029     inFile.close();
1030     return ERR_OK;
1031 }
1032 
SetDistributedEnabledByBundle(const sptr<NotificationBundleOption> & bundleOption,const std::string & deviceType,const bool enabled)1033 ErrCode NotificationPreferences::SetDistributedEnabledByBundle(const sptr<NotificationBundleOption> &bundleOption,
1034     const std::string &deviceType, const bool enabled)
1035 {
1036     ANS_LOGD("%{public}s", __FUNCTION__);
1037     if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) {
1038         return ERR_ANS_INVALID_PARAM;
1039     }
1040 
1041     std::lock_guard<std::mutex> lock(preferenceMutex_);
1042     NotificationPreferencesInfo::BundleInfo bundleInfo;
1043     bundleInfo.SetBundleName(bundleOption->GetBundleName());
1044     bundleInfo.SetBundleUid(bundleOption->GetUid());
1045     bundleInfo.SetEnableNotification(CheckApiCompatibility(bundleOption));
1046     bool storeDBResult = true;
1047     storeDBResult = preferncesDB_->PutDistributedEnabledForBundle(deviceType, bundleInfo, enabled);
1048     return storeDBResult ? ERR_OK : ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED;
1049 }
1050 
IsDistributedEnabledByBundle(const sptr<NotificationBundleOption> & bundleOption,const std::string & deviceType,bool & enabled)1051 ErrCode NotificationPreferences::IsDistributedEnabledByBundle(const sptr<NotificationBundleOption> &bundleOption,
1052     const std::string &deviceType, bool &enabled)
1053 {
1054     ANS_LOGD("%{public}s", __FUNCTION__);
1055     if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) {
1056         return ERR_ANS_INVALID_PARAM;
1057     }
1058 
1059     std::lock_guard<std::mutex> lock(preferenceMutex_);
1060     NotificationPreferencesInfo::BundleInfo bundleInfo;
1061     bundleInfo.SetBundleName(bundleOption->GetBundleName());
1062     bundleInfo.SetBundleUid(bundleOption->GetUid());
1063     bundleInfo.SetEnableNotification(CheckApiCompatibility(bundleOption));
1064     bool storeDBResult = true;
1065     storeDBResult = preferncesDB_->GetDistributedEnabledForBundle(deviceType, bundleInfo, enabled);
1066     return storeDBResult ? ERR_OK : ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED;
1067 }
1068 
SetSmartReminderEnabled(const std::string & deviceType,const bool enabled)1069 ErrCode NotificationPreferences::SetSmartReminderEnabled(const std::string &deviceType, const bool enabled)
1070 {
1071     ANS_LOGD("%{public}s", __FUNCTION__);
1072     if (deviceType.empty()) {
1073         return ERR_ANS_INVALID_PARAM;
1074     }
1075 
1076     std::lock_guard<std::mutex> lock(preferenceMutex_);
1077     bool storeDBResult = true;
1078     storeDBResult = preferncesDB_->SetSmartReminderEnabled(deviceType, enabled);
1079     return storeDBResult ? ERR_OK : ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED;
1080 }
1081 
IsSmartReminderEnabled(const std::string & deviceType,bool & enabled)1082 ErrCode NotificationPreferences::IsSmartReminderEnabled(const std::string &deviceType, bool &enabled)
1083 {
1084     ANS_LOGD("%{public}s", __FUNCTION__);
1085     if (deviceType.empty()) {
1086         return ERR_ANS_INVALID_PARAM;
1087     }
1088 
1089     std::lock_guard<std::mutex> lock(preferenceMutex_);
1090     bool storeDBResult = true;
1091     storeDBResult = preferncesDB_->IsSmartReminderEnabled(deviceType, enabled);
1092     return storeDBResult ? ERR_OK : ERR_ANS_PREFERENCES_NOTIFICATION_DB_OPERATION_FAILED;
1093 }
1094 
InitSettingFromDisturbDB(int32_t userId)1095 void NotificationPreferences::InitSettingFromDisturbDB(int32_t userId)
1096 {
1097     ANS_LOGI("%{public}s userId is %{public}d", __FUNCTION__, userId);
1098     std::lock_guard<std::mutex> lock(preferenceMutex_);
1099     if (preferncesDB_ != nullptr) {
1100         preferncesDB_->ParseFromDisturbeDB(preferencesInfo_, userId);
1101     }
1102 }
1103 
RemoveSettings(int32_t userId)1104 void NotificationPreferences::RemoveSettings(int32_t userId)
1105 {
1106     ANS_LOGD("%{public}s", __FUNCTION__);
1107     std::lock_guard<std::mutex> lock(preferenceMutex_);
1108     preferencesInfo_.RemoveNotificationEnable(userId);
1109     preferencesInfo_.RemoveDoNotDisturbDate(userId);
1110     if (preferncesDB_ != nullptr) {
1111         preferncesDB_->RemoveNotificationEnable(userId);
1112         preferncesDB_->RemoveDoNotDisturbDate(userId);
1113         preferncesDB_->DropUserTable(userId);
1114     }
1115 }
1116 
CheckApiCompatibility(const sptr<NotificationBundleOption> & bundleOption) const1117 bool NotificationPreferences::CheckApiCompatibility(const sptr<NotificationBundleOption> &bundleOption) const
1118 {
1119     ANS_LOGD("%{public}s", __FUNCTION__);
1120     std::shared_ptr<BundleManagerHelper> bundleManager = BundleManagerHelper::GetInstance();
1121     if (bundleManager == nullptr) {
1122         return false;
1123     }
1124     return bundleManager->CheckApiCompatibility(bundleOption);
1125 }
1126 
RemoveAnsBundleDbInfo(const sptr<NotificationBundleOption> & bundleOption)1127 void NotificationPreferences::RemoveAnsBundleDbInfo(const sptr<NotificationBundleOption> &bundleOption)
1128 {
1129     ANS_LOGE("%{public}s", __FUNCTION__);
1130     if (preferncesDB_ != nullptr && bundleOption != nullptr) {
1131         preferncesDB_->RemoveAnsBundleDbInfo(bundleOption->GetBundleName(), bundleOption->GetUid());
1132     }
1133 }
1134 
RemoveEnabledDbByBundle(const sptr<NotificationBundleOption> & bundleOption)1135 void NotificationPreferences::RemoveEnabledDbByBundle(const sptr<NotificationBundleOption> &bundleOption)
1136 {
1137     ANS_LOGE("%{public}s", __FUNCTION__);
1138     if (preferncesDB_ != nullptr && bundleOption != nullptr) {
1139         std::lock_guard<std::mutex> lock(preferenceMutex_);
1140         preferncesDB_->RemoveEnabledDbByBundleName(bundleOption->GetBundleName(), bundleOption->GetUid());
1141     }
1142 }
1143 
GetBundleSoundPermission(bool & allPackage,std::set<std::string> & bundleNames)1144 bool NotificationPreferences::GetBundleSoundPermission(bool &allPackage, std::set<std::string> &bundleNames)
1145 {
1146     ANS_LOGD("%{public}s", __FUNCTION__);
1147     std::string value = "";
1148     int32_t userId = -1;
1149     OsAccountManagerHelper::GetInstance().GetCurrentCallingUserId(userId);
1150     if (GetKvFromDb("RING_TRUSTLIST_PKG", value, userId) != ERR_OK) {
1151         ANS_LOGD("Get bundle sound permission failed.");
1152         return false;
1153     }
1154 
1155     ANS_LOGD("The bundle permission is :%{public}s.", value.c_str());
1156     nlohmann::json jsonPermission = nlohmann::json::parse(value, nullptr, false);
1157     if (jsonPermission.is_null() || jsonPermission.empty()) {
1158         ANS_LOGE("Invalid JSON object");
1159         return false;
1160     }
1161     if (jsonPermission.is_discarded() || !jsonPermission.is_array()) {
1162         ANS_LOGE("Parse bundle permission failed due to data is discarded or not array");
1163         return false;
1164     }
1165 
1166     for (const auto &item : jsonPermission) {
1167         bundleNames.insert(item);
1168         if (item == "ALL_PKG") {
1169             allPackage = true;
1170         }
1171     }
1172     return true;
1173 }
1174 
SetKvToDb(const std::string & key,const std::string & value,const int32_t & userId)1175 int32_t NotificationPreferences::SetKvToDb(
1176     const std::string &key, const std::string &value, const int32_t &userId)
1177 {
1178     if (preferncesDB_ == nullptr) {
1179         return ERR_ANS_SERVICE_NOT_READY;
1180     }
1181     return preferncesDB_->SetKvToDb(key, value, userId);
1182 }
1183 
SetByteToDb(const std::string & key,const std::vector<uint8_t> & value,const int32_t & userId)1184 int32_t NotificationPreferences::SetByteToDb(
1185     const std::string &key, const std::vector<uint8_t> &value, const int32_t &userId)
1186 {
1187     if (preferncesDB_ == nullptr) {
1188         return ERR_ANS_SERVICE_NOT_READY;
1189     }
1190     return preferncesDB_->SetByteToDb(key, value, userId);
1191 }
1192 
GetKvFromDb(const std::string & key,std::string & value,const int32_t & userId)1193 int32_t NotificationPreferences::GetKvFromDb(
1194     const std::string &key, std::string &value, const int32_t &userId)
1195 {
1196     if (preferncesDB_ == nullptr) {
1197         return ERR_ANS_SERVICE_NOT_READY;
1198     }
1199     return preferncesDB_->GetKvFromDb(key, value, userId);
1200 }
1201 
GetByteFromDb(const std::string & key,std::vector<uint8_t> & value,const int32_t & userId)1202 int32_t NotificationPreferences::GetByteFromDb(
1203     const std::string &key, std::vector<uint8_t> &value, const int32_t &userId)
1204 {
1205     if (preferncesDB_ == nullptr) {
1206         return ERR_ANS_SERVICE_NOT_READY;
1207     }
1208     return preferncesDB_->GetByteFromDb(key, value, userId);
1209 }
1210 
GetBatchKvsFromDb(const std::string & key,std::unordered_map<std::string,std::string> & values,const int32_t & userId)1211 int32_t NotificationPreferences::GetBatchKvsFromDb(
1212     const std::string &key, std::unordered_map<std::string, std::string> &values, const int32_t &userId)
1213 {
1214     if (preferncesDB_ == nullptr) {
1215         return ERR_ANS_SERVICE_NOT_READY;
1216     }
1217     return preferncesDB_->GetBatchKvsFromDb(key, values, userId);
1218 }
1219 
DeleteKvFromDb(const std::string & key,const int32_t & userId)1220 int32_t NotificationPreferences::DeleteKvFromDb(const std::string &key, const int32_t &userId)
1221 {
1222     if (preferncesDB_ == nullptr) {
1223         return ERR_ANS_SERVICE_NOT_READY;
1224     }
1225     return preferncesDB_->DeleteKvFromDb(key, userId);
1226 }
1227 
DeleteBatchKvFromDb(const std::vector<std::string> & keys,const int32_t & userId)1228 int32_t NotificationPreferences::DeleteBatchKvFromDb(const std::vector<std::string> &keys,  const int32_t &userId)
1229 {
1230     if (preferncesDB_ == nullptr) {
1231         return ERR_ANS_SERVICE_NOT_READY;
1232     }
1233     return preferncesDB_->DeleteBatchKvFromDb(keys, userId);
1234 }
1235 
IsAgentRelationship(const std::string & agentBundleName,const std::string & sourceBundleName)1236 bool NotificationPreferences::IsAgentRelationship(const std::string &agentBundleName,
1237     const std::string &sourceBundleName)
1238 {
1239     if (AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_AGENT_CONTROLLER)) {
1240         ANS_LOGD("Client has agent permission.");
1241         return true;
1242     }
1243 
1244     if (preferncesDB_ == nullptr) {
1245         ANS_LOGD("perferencdDb is null.");
1246         return false;
1247     }
1248 
1249     return preferncesDB_->IsAgentRelationship(agentBundleName, sourceBundleName);
1250 }
1251 
GetAdditionalConfig(const std::string & key)1252 std::string NotificationPreferences::GetAdditionalConfig(const std::string &key)
1253 {
1254     if (preferncesDB_ == nullptr) {
1255         return "";
1256     }
1257     return preferncesDB_->GetAdditionalConfig(key);
1258 }
1259 }  // namespace Notification
1260 }  // namespace OHOS
1261