1 /*
2 * Copyright (c) 2021-2023 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 "advanced_notification_service.h"
17
18 #include <functional>
19 #include <iomanip>
20 #include <sstream>
21
22 #include "accesstoken_kit.h"
23 #include "ans_inner_errors.h"
24 #include "ans_log_wrapper.h"
25 #include "errors.h"
26
27 #include "ipc_skeleton.h"
28 #include "access_token_helper.h"
29 #include "notification_constant.h"
30 #include "notification_request.h"
31 #include "os_account_manager.h"
32 #include "hitrace_meter_adapter.h"
33 #include "reminder_data_manager.h"
34 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
35 #include "distributed_notification_manager.h"
36 #include "distributed_preferences.h"
37 #include "distributed_screen_status_manager.h"
38 #endif
39
40 #include "advanced_notification_inline.cpp"
41
42 namespace OHOS {
43 namespace Notification {
CheckReminderPermission()44 inline bool AdvancedNotificationService::CheckReminderPermission()
45 {
46 Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
47 ErrCode result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(
48 callerToken, "ohos.permission.PUBLISH_AGENT_REMINDER");
49 return result == Security::AccessToken::PermissionState::PERMISSION_GRANTED;
50 }
51
PublishReminder(sptr<ReminderRequest> &reminder)52 ErrCode AdvancedNotificationService::PublishReminder(sptr<ReminderRequest> &reminder)
53 {
54 HITRACE_METER_NAME(HITRACE_TAG_OHOS, __PRETTY_FUNCTION__);
55 ANSR_LOGI("Publish reminder");
56 if (!reminder) {
57 ANSR_LOGE("ReminderRequest object is nullptr");
58 return ERR_ANS_INVALID_PARAM;
59 }
60
61 std::string bundle = GetClientBundleName();
62 if (!CheckReminderPermission()) {
63 ANSR_LOGW("Permission denied: ohos.permission.PUBLISH_AGENT_REMINDER");
64 return ERR_REMINDER_PERMISSION_DENIED;
65 }
66 if (!AllowUseReminder(bundle)) {
67 ANSR_LOGW("The number of reminders exceeds the limit[0].");
68 return ERR_REMINDER_NUMBER_OVERLOAD;
69 }
70 ANSR_LOGD("is system app: %{public}d", AccessTokenHelper::IsSystemApp());
71 reminder->SetSystemApp(AccessTokenHelper::IsSystemApp());
72 sptr<NotificationRequest> notificationRequest = reminder->GetNotificationRequest();
73 reminder->InitCreatorBundleName(bundle);
74 reminder->InitCreatorUid(IPCSkeleton::GetCallingUid());
75 if (reminder->GetWantAgentInfo() == nullptr || reminder->GetMaxScreenWantAgentInfo() == nullptr) {
76 ANSR_LOGE("wantagent info is nullptr");
77 return ERR_ANS_INVALID_PARAM;
78 }
79 std::string wantAgentName = reminder->GetWantAgentInfo()->pkgName;
80 std::string msWantAgentName = reminder->GetMaxScreenWantAgentInfo()->pkgName;
81 if (wantAgentName != msWantAgentName && wantAgentName != "" && msWantAgentName != "") {
82 ANSR_LOGE("wantAgentName is not same to msWantAgentName, wantAgentName:%{public}s, msWantAgentName:%{public}s",
83 wantAgentName.c_str(), msWantAgentName.c_str());
84 return ERR_ANS_INVALID_PARAM;
85 }
86 if (wantAgentName != bundle && wantAgentName != "") {
87 ANSR_LOGI("Set agent reminder, bundle:%{public}s, wantAgentName:%{public}s", bundle.c_str(),
88 wantAgentName.c_str());
89 SetAgentNotification(notificationRequest, wantAgentName);
90 } else if (msWantAgentName != bundle && msWantAgentName != "") {
91 ANSR_LOGI("Set agent reminder, bundle:%{public}s, msWantAgentName:%{public}s", bundle.c_str(),
92 msWantAgentName.c_str());
93 SetAgentNotification(notificationRequest, msWantAgentName);
94 }
95 sptr<NotificationBundleOption> bundleOption = nullptr;
96 ErrCode result = PrepareNotificationInfo(notificationRequest, bundleOption);
97 if (result != ERR_OK) {
98 ANSR_LOGW("PrepareNotificationInfo fail");
99 return result;
100 }
101 bool allowedNotify = false;
102 result = IsAllowedNotifySelf(bundleOption, allowedNotify);
103 if (!reminder->IsSystemApp() && (result != ERR_OK || !allowedNotify)) {
104 ANSR_LOGW("The application does not request enable notification");
105 return ERR_REMINDER_NOTIFICATION_NOT_ENABLE;
106 }
107 auto rdm = ReminderDataManager::GetInstance();
108 if (rdm == nullptr) {
109 return ERR_NO_INIT;
110 }
111 return rdm->PublishReminder(reminder, bundleOption);
112 }
113
CancelReminder(const int32_t reminderId)114 ErrCode AdvancedNotificationService::CancelReminder(const int32_t reminderId)
115 {
116 HITRACE_METER_NAME(HITRACE_TAG_OHOS, __PRETTY_FUNCTION__);
117 ANSR_LOGI("Cancel Reminder");
118 if (!CheckReminderPermission()) {
119 ANSR_LOGW("Permission denied: ohos.permission.PUBLISH_AGENT_REMINDER");
120 return ERR_REMINDER_PERMISSION_DENIED;
121 }
122
123 sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
124 if (bundleOption == nullptr) {
125 return ERR_ANS_INVALID_BUNDLE;
126 }
127 auto rdm = ReminderDataManager::GetInstance();
128 if (rdm == nullptr) {
129 return ERR_NO_INIT;
130 }
131 return rdm->CancelReminder(reminderId, bundleOption);
132 }
133
CancelAllReminders()134 ErrCode AdvancedNotificationService::CancelAllReminders()
135 {
136 HITRACE_METER_NAME(HITRACE_TAG_OHOS, __PRETTY_FUNCTION__);
137 ANSR_LOGI("Cancel all reminders");
138 if (!CheckReminderPermission()) {
139 ANSR_LOGW("Permission denied: ohos.permission.PUBLISH_AGENT_REMINDER");
140 return ERR_REMINDER_PERMISSION_DENIED;
141 }
142
143 sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
144 if (bundleOption == nullptr) {
145 return ERR_ANS_INVALID_BUNDLE;
146 }
147 int32_t userId = -1;
148 AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(bundleOption->GetUid(), userId);
149 auto rdm = ReminderDataManager::GetInstance();
150 if (rdm == nullptr) {
151 return ERR_NO_INIT;
152 }
153 return rdm->CancelAllReminders(bundleOption->GetBundleName(), userId, bundleOption->GetUid());
154 }
155
156
GetValidReminders(std::vector<sptr<ReminderRequest>> &reminders)157 ErrCode AdvancedNotificationService::GetValidReminders(std::vector<sptr<ReminderRequest>> &reminders)
158 {
159 HITRACE_METER_NAME(HITRACE_TAG_OHOS, __PRETTY_FUNCTION__);
160 ANSR_LOGI("GetValidReminders");
161 if (!CheckReminderPermission()) {
162 ANSR_LOGW("Permission denied: ohos.permission.PUBLISH_AGENT_REMINDER");
163 return ERR_REMINDER_PERMISSION_DENIED;
164 }
165
166 reminders.clear();
167 sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
168 if (bundleOption == nullptr) {
169 return ERR_ANS_INVALID_BUNDLE;
170 }
171 auto rdm = ReminderDataManager::GetInstance();
172 if (rdm == nullptr) {
173 return ERR_NO_INIT;
174 }
175 rdm->GetValidReminders(bundleOption, reminders);
176 ANSR_LOGD("Valid reminders size=%{public}zu", reminders.size());
177 return ERR_OK;
178 }
179
AddExcludeDate(const int32_t reminderId, const uint64_t date)180 ErrCode AdvancedNotificationService::AddExcludeDate(const int32_t reminderId, const uint64_t date)
181 {
182 HITRACE_METER_NAME(HITRACE_TAG_OHOS, __PRETTY_FUNCTION__);
183 ANSR_LOGI("Add Exclude Date");
184 if (!CheckReminderPermission()) {
185 ANSR_LOGW("Permission denied: ohos.permission.PUBLISH_AGENT_REMINDER");
186 return ERR_REMINDER_PERMISSION_DENIED;
187 }
188
189 sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
190 if (bundleOption == nullptr) {
191 ANSR_LOGW("Generate bundle option failed!");
192 return ERR_ANS_INVALID_BUNDLE;
193 }
194 auto rdm = ReminderDataManager::GetInstance();
195 if (rdm == nullptr) {
196 ANSR_LOGW("Reminder data manager not init!");
197 return ERR_NO_INIT;
198 }
199 return rdm->AddExcludeDate(reminderId, date, bundleOption);
200 }
201
DelExcludeDates(const int32_t reminderId)202 ErrCode AdvancedNotificationService::DelExcludeDates(const int32_t reminderId)
203 {
204 HITRACE_METER_NAME(HITRACE_TAG_OHOS, __PRETTY_FUNCTION__);
205 ANSR_LOGI("Del Exclude Dates");
206 if (!CheckReminderPermission()) {
207 ANSR_LOGW("Permission denied: ohos.permission.PUBLISH_AGENT_REMINDER");
208 return ERR_REMINDER_PERMISSION_DENIED;
209 }
210
211 sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
212 if (bundleOption == nullptr) {
213 ANSR_LOGW("Generate bundle option failed!");
214 return ERR_ANS_INVALID_BUNDLE;
215 }
216 auto rdm = ReminderDataManager::GetInstance();
217 if (rdm == nullptr) {
218 ANSR_LOGW("Reminder data manager not init!");
219 return ERR_NO_INIT;
220 }
221 return rdm->DelExcludeDates(reminderId, bundleOption);
222 }
223
GetExcludeDates(const int32_t reminderId, std::vector<uint64_t>& dates)224 ErrCode AdvancedNotificationService::GetExcludeDates(const int32_t reminderId, std::vector<uint64_t>& dates)
225 {
226 HITRACE_METER_NAME(HITRACE_TAG_OHOS, __PRETTY_FUNCTION__);
227 ANSR_LOGI("Get Exclude Dates");
228 if (!CheckReminderPermission()) {
229 ANSR_LOGW("Permission denied: ohos.permission.PUBLISH_AGENT_REMINDER");
230 return ERR_REMINDER_PERMISSION_DENIED;
231 }
232
233 sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
234 if (bundleOption == nullptr) {
235 ANSR_LOGW("Generate bundle option failed!");
236 return ERR_ANS_INVALID_BUNDLE;
237 }
238 auto rdm = ReminderDataManager::GetInstance();
239 if (rdm == nullptr) {
240 ANSR_LOGW("Reminder data manager not init!");
241 return ERR_NO_INIT;
242 }
243 return rdm->GetExcludeDates(reminderId, bundleOption, dates);
244 }
245
246 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
GetRemindType()247 NotificationConstant::RemindType AdvancedNotificationService::GetRemindType()
248 {
249 bool remind = localScreenOn_;
250 if (distributedReminderPolicy_ == NotificationConstant::DistributedReminderPolicy::DEFAULT) {
251 bool remoteUsing = false;
252 ErrCode result = DistributedScreenStatusManager::GetInstance()->CheckRemoteDevicesIsUsing(remoteUsing);
253 if (result != ERR_OK) {
254 remind = true;
255 }
256 if (!localScreenOn_ && !remoteUsing) {
257 remind = true;
258 }
259 } else if (distributedReminderPolicy_ == NotificationConstant::DistributedReminderPolicy::ALWAYS_REMIND) {
260 remind = true;
261 } else if (distributedReminderPolicy_ == NotificationConstant::DistributedReminderPolicy::DO_NOT_REMIND) {
262 remind = false;
263 }
264
265 if (localScreenOn_) {
266 if (remind) {
267 return NotificationConstant::RemindType::DEVICE_ACTIVE_REMIND;
268 } else {
269 return NotificationConstant::RemindType::DEVICE_ACTIVE_DONOT_REMIND;
270 }
271 } else {
272 if (remind) {
273 return NotificationConstant::RemindType::DEVICE_IDLE_REMIND;
274 } else {
275 return NotificationConstant::RemindType::DEVICE_IDLE_DONOT_REMIND;
276 }
277 }
278 }
279 #endif
280
GetDeviceRemindType(NotificationConstant::RemindType &remindType)281 ErrCode AdvancedNotificationService::GetDeviceRemindType(NotificationConstant::RemindType &remindType)
282 {
283 ANS_LOGD("%{public}s", __FUNCTION__);
284
285 bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
286 if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
287 return ERR_ANS_NON_SYSTEM_APP;
288 }
289
290 if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
291 return ERR_ANS_PERMISSION_DENIED;
292 }
293
294 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
295 if (notificationSvrQueue_ == nullptr) {
296 ANS_LOGE("Serial queue is invalid.");
297 return ERR_ANS_INVALID_PARAM;
298 }
299 ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() { remindType = GetRemindType(); }));
300 notificationSvrQueue_->wait(handler);
301 return ERR_OK;
302 #else
303 return ERR_INVALID_OPERATION;
304 #endif
305 }
306
SetNotificationRemindType(sptr<Notification> notification, bool isLocal)307 ErrCode AdvancedNotificationService::SetNotificationRemindType(sptr<Notification> notification, bool isLocal)
308 {
309 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
310 notification->SetRemindType(GetRemindType());
311 #else
312 notification->SetRemindType(NotificationConstant::RemindType::NONE);
313 #endif
314 return ERR_OK;
315 }
316 } // namespace Notification
317 } // namespace OHOS
318