• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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