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 "ans_log_wrapper.h"
20 #include "ans_const_define.h"
21 #include "common_event_support.h"
22 #include "common_event_manager.h"
23 #include "reminder_request_calendar.h"
24 #include "in_process_call_wrapper.h"
25 #include "ipc_skeleton.h"
26 #include "notification_slot.h"
27 #include "os_account_manager.h"
28 #include "reminder_event_manager.h"
29 #include "time_service_client.h"
30 #include "singleton.h"
31 #include "locale_config.h"
32 #include "datashare_predicates_object.h"
33 #include "datashare_value_object.h"
34 #include "datashare_helper.h"
35 #include "data_share_permission.h"
36 #include "datashare_errno.h"
37 #include "datashare_template.h"
38 #include "system_ability_definition.h"
39 #include "app_mgr_constants.h"
40 #include "iservice_registry.h"
41 #include "config_policy_utils.h"
42 #include "hitrace_meter_adapter.h"
43 #ifdef HAS_HISYSEVENT_PART
44 #include "hisysevent.h"
45 #endif
46
47 namespace OHOS {
48 namespace Notification {
49 namespace {
50 constexpr int32_t ALL_SA_READY_FLAG = 2; // bundle service and ability service ready.
51 // The maximum number of applications that can be displayed at a time
52 constexpr int32_t ONE_HAP_MAX_NUMBER_SHOW_AT_ONCE = 10;
53 // The maximum number of system that can be displayed at a time
54 constexpr int32_t TOTAL_MAX_NUMBER_SHOW_AT_ONCE = 500;
55 // The maximun number of system that can be start extension count
56 constexpr int32_t TOTAL_MAX_NUMBER_START_EXTENSION = 100;
57 constexpr int32_t CONNECT_EXTENSION_INTERVAL = 100;
58 }
59
IsSystemReady()60 bool ReminderDataManager::IsSystemReady()
61 {
62 return saReadyFlag_ >= ALL_SA_READY_FLAG;
63 }
64
IsActionButtonDataShareValid(const sptr<ReminderRequest> & reminder,const uint32_t callerTokenId)65 bool ReminderDataManager::IsActionButtonDataShareValid(const sptr<ReminderRequest>& reminder,
66 const uint32_t callerTokenId)
67 {
68 auto actionButtonMap = reminder->GetActionButtons();
69 for (auto it = actionButtonMap.begin(); it != actionButtonMap.end(); ++it) {
70 ReminderRequest::ActionButtonInfo& buttonInfo = it->second;
71 if (buttonInfo.dataShareUpdate->uri.empty()) {
72 continue;
73 }
74 Uri uri(buttonInfo.dataShareUpdate->uri);
75 auto ret = DataShare::DataSharePermission::VerifyPermission(callerTokenId, uri, false);
76 if (ret != DataShare::E_OK) {
77 ANSR_LOGE("publish failed, DataSharePermission::VerifyPermission return error[%{public}d],",
78 static_cast<int32_t>(ret));
79 return false;
80 }
81 }
82 return true;
83 }
84
HandleAutoDeleteReminder(const int32_t notificationId,const int32_t uid,const int64_t autoDeletedTime)85 void ReminderDataManager::HandleAutoDeleteReminder(const int32_t notificationId, const int32_t uid,
86 const int64_t autoDeletedTime)
87 {
88 ANSR_LOGI("auto delete reminder start");
89 std::vector<sptr<ReminderRequest>> showedReminder;
90 {
91 std::lock_guard<std::mutex> lock(ReminderDataManager::SHOW_MUTEX);
92 showedReminder = showedReminderVector_;
93 }
94 for (auto reminder : showedReminder) {
95 if (reminder == nullptr) {
96 continue;
97 }
98
99 if (reminder->GetUid() != uid || notificationId != reminder->GetNotificationId() ||
100 reminder->GetAutoDeletedTime() != autoDeletedTime) {
101 continue;
102 }
103 CloseReminder(reminder, true);
104 UpdateAppDatabase(reminder, ReminderRequest::ActionButtonType::CLOSE);
105 CheckNeedNotifyStatus(reminder, ReminderRequest::ActionButtonType::CLOSE);
106 }
107 StartRecentReminder();
108 }
109
OnBundleMgrServiceStart()110 void ReminderDataManager::OnBundleMgrServiceStart()
111 {
112 saReadyFlag_.fetch_add(1);
113 }
114
OnAbilityMgrServiceStart()115 void ReminderDataManager::OnAbilityMgrServiceStart()
116 {
117 saReadyFlag_.fetch_add(1);
118 }
119
GetCustomRingFileDesc(const sptr<ReminderRequest> & reminder,Global::Resource::ResourceManager::RawFileDescriptor & desc)120 bool ReminderDataManager::GetCustomRingFileDesc(const sptr<ReminderRequest>& reminder,
121 Global::Resource::ResourceManager::RawFileDescriptor& desc)
122 {
123 // obtains the resource manager
124 std::lock_guard<std::mutex> locker(resourceMutex_);
125 soundResource_ = GetResourceMgr(reminder->GetBundleName(), reminder->GetUid());
126 if (soundResource_ == nullptr) {
127 ANSR_LOGE("GetResourceMgr fail.");
128 return false;
129 }
130 auto result = soundResource_->GetRawFileDescriptor(reminder->GetCustomRingUri(), desc);
131 if (result != Global::Resource::SUCCESS) {
132 ANSR_LOGE("GetRawFileDescriptor fail[%{public}d].", static_cast<int32_t>(result));
133 return false;
134 }
135 return true;
136 }
137
CloseCustomRingFileDesc(const int32_t reminderId,const std::string & customRingUri)138 void ReminderDataManager::CloseCustomRingFileDesc(const int32_t reminderId, const std::string& customRingUri)
139 {
140 std::lock_guard<std::mutex> locker(resourceMutex_);
141 if (soundResource_ == nullptr) {
142 ANSR_LOGW("ResourceManager is nullptr.");
143 return;
144 }
145 auto result = soundResource_->CloseRawFileDescriptor(customRingUri);
146 if (result != Global::Resource::SUCCESS) {
147 ANSR_LOGW("CloseRawFileDescriptor fail[%{public}d]", static_cast<int32_t>(result));
148 }
149 ANSR_LOGI("Stop custom sound, reminderId:[%{public}d].", reminderId);
150 soundResource_ = nullptr;
151 }
152
ReportSysEvent(const sptr<ReminderRequest> & reminder)153 void ReminderDataManager::ReportSysEvent(const sptr<ReminderRequest>& reminder)
154 {
155 #ifdef HAS_HISYSEVENT_PART
156 std::string event = "ALARM_TRIGGER";
157 std::string bundleName = reminder->GetBundleName();
158 int32_t uid = reminder->GetUid();
159 int32_t type = static_cast<int32_t>(reminder->GetReminderType());
160 int32_t repeat = static_cast<int32_t>(reminder->IsRepeat());
161 uint64_t triggerTime = reminder->GetTriggerTimeInMilli();
162 int32_t ringTime = static_cast<int32_t>(reminder->GetRingDuration());
163 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::NOTIFICATION, event, HiviewDFX::HiSysEvent::EventType::STATISTIC,
164 "UID", uid, "NAME", bundleName, "TYPE", type, "REPEAT", repeat, "TRIGGER_TIME", triggerTime,
165 "RING_TIME", ringTime);
166 #endif
167 }
168
CheckShowLimit(std::unordered_map<std::string,int32_t> & limits,int32_t & totalCount,sptr<ReminderRequest> & reminder)169 bool ReminderDataManager::CheckShowLimit(std::unordered_map<std::string, int32_t>& limits, int32_t& totalCount,
170 sptr<ReminderRequest>& reminder)
171 {
172 if (totalCount > TOTAL_MAX_NUMBER_SHOW_AT_ONCE) {
173 ANSR_LOGW("The maximum number of displays that can be displayed at a time has been reached.");
174 return false;
175 }
176 ++totalCount;
177 std::string key = std::to_string(reminder->GetUid()) + "_" + std::to_string(reminder->GetTriggerTimeInMilli());
178 auto iter = limits.find(key);
179 if (iter == limits.end()) {
180 limits[key] = 1;
181 return true;
182 }
183 if (iter->second > ONE_HAP_MAX_NUMBER_SHOW_AT_ONCE) {
184 ANSR_LOGW("The maximum number of displays that can be displayed in a single app[%{public}s] has been reached",
185 reminder->GetBundleName().c_str());
186 return false;
187 }
188 ++iter->second;
189 return true;
190 }
191
OnDataShareInsertOrDelete()192 void ReminderDataManager::OnDataShareInsertOrDelete()
193 {
194 LoadShareReminders();
195 std::vector<sptr<ReminderRequest>> immediatelyReminders;
196 std::vector<sptr<ReminderRequest>> extensionReminders;
197 CheckReminderTime(immediatelyReminders, extensionReminders);
198 HandleImmediatelyShow(immediatelyReminders, false);
199 StartRecentReminder();
200 }
201
OnDataShareUpdate(const std::map<std::string,sptr<ReminderRequest>> & reminders)202 void ReminderDataManager::OnDataShareUpdate(const std::map<std::string, sptr<ReminderRequest>>& reminders)
203 {
204 UpdateShareReminders(reminders);
205 }
206
UpdateShareReminders(const std::map<std::string,sptr<ReminderRequest>> & reminders)207 void ReminderDataManager::UpdateShareReminders(const std::map<std::string, sptr<ReminderRequest>>& reminders)
208 {
209 std::lock_guard<std::mutex> locker(ReminderDataManager::MUTEX);
210 for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) {
211 if (!(*it)->IsShare() || (*it)->GetReminderType() != ReminderRequest::ReminderType::CALENDAR) {
212 continue;
213 }
214 int32_t reminderId = (*it)->GetReminderId();
215 std::string identifier = (*it)->GetIdentifier();
216 auto iter = reminders.find(identifier);
217 if (iter == reminders.end()) {
218 continue;
219 }
220 ReminderRequestCalendar* calendar = static_cast<ReminderRequestCalendar*>((*it).GetRefPtr());
221 calendar->Copy(iter->second);
222 if ((*it)->IsShowing()) {
223 ShowReminder((*it), false, false, false, false);
224 }
225 }
226 }
227
AsyncStartExtensionAbility(const sptr<ReminderRequest> & reminder,int32_t times,const int8_t type,int32_t & count)228 void ReminderDataManager::AsyncStartExtensionAbility(const sptr<ReminderRequest> &reminder, int32_t times,
229 const int8_t type, int32_t& count)
230 {
231 auto manager = ReminderDataManager::GetInstance();
232 if (manager == nullptr) {
233 ANSR_LOGW("ReminderDataManager is nullptr.");
234 return;
235 }
236 if (!manager->IsSystemReady()) {
237 ANSR_LOGW("bundle service or ability service not ready.");
238 return;
239 }
240 if (!reminder->IsSystemApp()) {
241 ANSR_LOGI("Start extension ability failed, is not system app");
242 return;
243 }
244 if (count > TOTAL_MAX_NUMBER_START_EXTENSION) {
245 ANSR_LOGW("The maximum number of start extension has been reached.");
246 return;
247 }
248 ++count;
249 times--;
250 bool ret = ReminderDataManager::StartExtensionAbility(reminder, type);
251 if (!ret && times > 0 && serviceQueue_ != nullptr) {
252 ANSR_LOGD("StartExtensionAbilty failed, reminder times: %{public}d", times);
253 ffrt::task_attr taskAttr;
254 taskAttr.delay(CONNECT_EXTENSION_INTERVAL);
255 auto callback = [reminder, times, type]() {
256 int32_t count = 0;
257 ReminderDataManager::AsyncStartExtensionAbility(reminder, times, type, count);
258 };
259 serviceQueue_->submit(callback, taskAttr);
260 }
261 }
262 }
263 }
264