1 /*
2  * Copyright (c) 2024-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 "reminder_data_manager.h"
17 
18 #include "ability_manager_client.h"
19 #include "access_token_helper.h"
20 #include "ans_log_wrapper.h"
21 #include "ans_const_define.h"
22 #include "common_event_support.h"
23 #include "common_event_manager.h"
24 #include "reminder_request_calendar.h"
25 #include "in_process_call_wrapper.h"
26 #ifdef DEVICE_STANDBY_ENABLE
27 #include "standby_service_client.h"
28 #include "allow_type.h"
29 #endif
30 #include "ipc_skeleton.h"
31 #include "notification_slot.h"
32 #include "os_account_manager.h"
33 #include "reminder_event_manager.h"
34 #include "time_service_client.h"
35 #include "singleton.h"
36 #include "locale_config.h"
37 #include "bundle_manager_helper.h"
38 #include "datashare_predicates_object.h"
39 #include "datashare_value_object.h"
40 #include "datashare_helper.h"
41 #include "data_share_permission.h"
42 #include "datashare_errno.h"
43 #include "datashare_template.h"
44 #include "system_ability_definition.h"
45 #include "app_mgr_constants.h"
46 #include "iservice_registry.h"
47 #include "config_policy_utils.h"
48 #include "hitrace_meter_adapter.h"
49 #ifdef HAS_HISYSEVENT_PART
50 #include "hisysevent.h"
51 #endif
52 
53 namespace OHOS {
54 namespace Notification {
55 namespace {
56 constexpr int32_t ALL_SA_READY_FLAG = 2;  // bundle service and ability service ready.
57 // The maximum number of applications that can be displayed at a time
58 constexpr int32_t ONE_HAP_MAX_NUMBER_SHOW_AT_ONCE = 10;
59 // The maximum number of system that can be displayed at a time
60 constexpr int32_t TOTAL_MAX_NUMBER_SHOW_AT_ONCE = 500;
61 }
62 
IsSystemReady()63 bool ReminderDataManager::IsSystemReady()
64 {
65     return saReadyFlag_ >= ALL_SA_READY_FLAG;
66 }
67 
IsActionButtonDataShareValid(const sptr<ReminderRequest> & reminder,const uint32_t callerTokenId)68 bool ReminderDataManager::IsActionButtonDataShareValid(const sptr<ReminderRequest>& reminder,
69     const uint32_t callerTokenId)
70 {
71     auto actionButtonMap = reminder->GetActionButtons();
72     for (auto it = actionButtonMap.begin(); it != actionButtonMap.end(); ++it) {
73         ReminderRequest::ActionButtonInfo& buttonInfo = it->second;
74         if (buttonInfo.dataShareUpdate->uri.empty()) {
75             continue;
76         }
77         Uri uri(buttonInfo.dataShareUpdate->uri);
78         auto ret = DataShare::DataSharePermission::VerifyPermission(callerTokenId, uri, false);
79         if (ret != DataShare::E_OK) {
80             ANSR_LOGE("publish failed, DataSharePermission::VerifyPermission return error[%{public}d],",
81                 static_cast<int32_t>(ret));
82             return false;
83         }
84     }
85     return true;
86 }
87 
HandleAutoDeleteReminder(const int32_t notificationId,const int32_t uid,const int64_t autoDeletedTime)88 void ReminderDataManager::HandleAutoDeleteReminder(const int32_t notificationId, const int32_t uid,
89     const int64_t autoDeletedTime)
90 {
91     ANSR_LOGI("auto delete reminder start");
92     std::vector<sptr<ReminderRequest>> showedReminder;
93     {
94         std::lock_guard<std::mutex> lock(ReminderDataManager::SHOW_MUTEX);
95         showedReminder = showedReminderVector_;
96     }
97     for (auto reminder : showedReminder) {
98         if (reminder == nullptr) {
99             continue;
100         }
101 
102         if (reminder->GetUid() != uid || notificationId != reminder->GetNotificationId() ||
103             reminder->GetAutoDeletedTime() != autoDeletedTime) {
104             continue;
105         }
106         CloseReminder(reminder, true);
107         UpdateAppDatabase(reminder, ReminderRequest::ActionButtonType::CLOSE);
108         CheckNeedNotifyStatus(reminder, ReminderRequest::ActionButtonType::CLOSE);
109     }
110     StartRecentReminder();
111 }
112 
OnBundleMgrServiceStart()113 void ReminderDataManager::OnBundleMgrServiceStart()
114 {
115     saReadyFlag_.fetch_add(1);
116 }
117 
OnAbilityMgrServiceStart()118 void ReminderDataManager::OnAbilityMgrServiceStart()
119 {
120     saReadyFlag_.fetch_add(1);
121 }
122 
GetCustomRingFileDesc(const sptr<ReminderRequest> & reminder,Global::Resource::ResourceManager::RawFileDescriptor & desc)123 bool ReminderDataManager::GetCustomRingFileDesc(const sptr<ReminderRequest>& reminder,
124     Global::Resource::ResourceManager::RawFileDescriptor& desc)
125 {
126     // obtains the resource manager
127     std::lock_guard<std::mutex> locker(resourceMutex_);
128     soundResource_ = GetResourceMgr(reminder->GetBundleName(), reminder->GetUid());
129     if (soundResource_ == nullptr) {
130         ANSR_LOGE("GetResourceMgr fail.");
131         return false;
132     }
133     auto result = soundResource_->GetRawFileDescriptor(reminder->GetCustomRingUri(), desc);
134     if (result != Global::Resource::SUCCESS) {
135         ANSR_LOGE("GetRawFileDescriptor fail[%{public}d].", static_cast<int32_t>(result));
136         return false;
137     }
138     return true;
139 }
140 
CloseCustomRingFileDesc(const int32_t reminderId,const std::string & customRingUri)141 void ReminderDataManager::CloseCustomRingFileDesc(const int32_t reminderId, const std::string& customRingUri)
142 {
143     std::lock_guard<std::mutex> locker(resourceMutex_);
144     if (soundResource_ == nullptr) {
145         ANSR_LOGW("ResourceManager is nullptr.");
146         return;
147     }
148     auto result = soundResource_->CloseRawFileDescriptor(customRingUri);
149     if (result != Global::Resource::SUCCESS) {
150         ANSR_LOGW("CloseRawFileDescriptor fail[%{public}d]", static_cast<int32_t>(result));
151     }
152     ANSR_LOGI("Stop custom sound, reminderId:[%{public}d].", reminderId);
153     soundResource_ = nullptr;
154 }
155 
ReportSysEvent(const sptr<ReminderRequest> & reminder)156 void ReminderDataManager::ReportSysEvent(const sptr<ReminderRequest>& reminder)
157 {
158 #ifdef HAS_HISYSEVENT_PART
159     std::string event = "ALARM_TRIGGER";
160     std::string bundleName = reminder->GetBundleName();
161     int32_t uid = reminder->GetUid();
162     int32_t type = static_cast<int32_t>(reminder->GetReminderType());
163     int32_t repeat = static_cast<int32_t>(reminder->IsRepeat());
164     uint64_t triggerTime = reminder->GetTriggerTimeInMilli();
165     int32_t ringTime = static_cast<int32_t>(reminder->GetRingDuration());
166     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::NOTIFICATION, event, HiviewDFX::HiSysEvent::EventType::STATISTIC,
167         "UID", uid, "NAME", bundleName, "TYPE", type, "REPEAT", repeat, "TRIGGER_TIME", triggerTime,
168         "RING_TIME", ringTime);
169 #endif
170 }
171 
CheckShowLimit(std::unordered_map<std::string,int32_t> & limits,int32_t & totalCount,sptr<ReminderRequest> & reminder)172 bool ReminderDataManager::CheckShowLimit(std::unordered_map<std::string, int32_t>& limits, int32_t& totalCount,
173     sptr<ReminderRequest>& reminder)
174 {
175     if (totalCount > TOTAL_MAX_NUMBER_SHOW_AT_ONCE) {
176         ANSR_LOGW("The maximum number of displays that can be displayed at a time has been reached.");
177         return false;
178     }
179     ++totalCount;
180     std::string key = std::to_string(reminder->GetUid()) + "_" + std::to_string(reminder->GetTriggerTimeInMilli());
181     auto iter = limits.find(key);
182     if (iter == limits.end()) {
183         limits[key] = 1;
184         return true;
185     }
186     if (iter->second > ONE_HAP_MAX_NUMBER_SHOW_AT_ONCE) {
187         ANSR_LOGW("The maximum number of displays that can be displayed in a single app[%{public}s] has been reached",
188             reminder->GetBundleName().c_str());
189         return false;
190     }
191     ++iter->second;
192     return true;
193 }
194 }
195 }
196