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 std::string bundleName = GetClientBundleName();
119 if (!CheckReminderPermission()) {
120 ANSR_LOGW("Permission denied: ohos.permission.PUBLISH_AGENT_REMINDER");
121 return ERR_REMINDER_PERMISSION_DENIED;
122 }
123
124 sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
125 if (bundleOption == nullptr) {
126 return ERR_ANS_INVALID_BUNDLE;
127 }
128 auto rdm = ReminderDataManager::GetInstance();
129 if (rdm == nullptr) {
130 return ERR_NO_INIT;
131 }
132 return rdm->CancelReminder(reminderId, bundleOption);
133 }
134
CancelAllReminders()135 ErrCode AdvancedNotificationService::CancelAllReminders()
136 {
137 HITRACE_METER_NAME(HITRACE_TAG_OHOS, __PRETTY_FUNCTION__);
138 ANSR_LOGI("Cancel all reminders");
139 std::string bundleName = GetClientBundleName();
140 if (!CheckReminderPermission()) {
141 ANSR_LOGW("Permission denied: ohos.permission.PUBLISH_AGENT_REMINDER");
142 return ERR_REMINDER_PERMISSION_DENIED;
143 }
144
145 sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
146 if (bundleOption == nullptr) {
147 return ERR_ANS_INVALID_BUNDLE;
148 }
149 int32_t userId = -1;
150 AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(bundleOption->GetUid(), userId);
151 auto rdm = ReminderDataManager::GetInstance();
152 if (rdm == nullptr) {
153 return ERR_NO_INIT;
154 }
155 return rdm->CancelAllReminders(bundleOption->GetBundleName(), userId, bundleOption->GetUid());
156 }
157
158
GetValidReminders(std::vector<sptr<ReminderRequest>> & reminders)159 ErrCode AdvancedNotificationService::GetValidReminders(std::vector<sptr<ReminderRequest>> &reminders)
160 {
161 HITRACE_METER_NAME(HITRACE_TAG_OHOS, __PRETTY_FUNCTION__);
162 ANSR_LOGI("GetValidReminders");
163 std::string bundleName = GetClientBundleName();
164 if (!CheckReminderPermission()) {
165 ANSR_LOGW("Permission denied: ohos.permission.PUBLISH_AGENT_REMINDER");
166 return ERR_REMINDER_PERMISSION_DENIED;
167 }
168
169 reminders.clear();
170 sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
171 if (bundleOption == nullptr) {
172 return ERR_ANS_INVALID_BUNDLE;
173 }
174 auto rdm = ReminderDataManager::GetInstance();
175 if (rdm == nullptr) {
176 return ERR_NO_INIT;
177 }
178 rdm->GetValidReminders(bundleOption, reminders);
179 ANSR_LOGD("Valid reminders size=%{public}zu", reminders.size());
180 return ERR_OK;
181 }
182
AddExcludeDate(const int32_t reminderId,const uint64_t date)183 ErrCode AdvancedNotificationService::AddExcludeDate(const int32_t reminderId, const uint64_t date)
184 {
185 HITRACE_METER_NAME(HITRACE_TAG_OHOS, __PRETTY_FUNCTION__);
186 ANSR_LOGI("Add Exclude Date");
187 std::string bundleName = GetClientBundleName();
188 if (!CheckReminderPermission()) {
189 ANSR_LOGW("Permission denied: ohos.permission.PUBLISH_AGENT_REMINDER");
190 return ERR_REMINDER_PERMISSION_DENIED;
191 }
192
193 sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
194 if (bundleOption == nullptr) {
195 ANSR_LOGW("Generate bundle option failed!");
196 return ERR_ANS_INVALID_BUNDLE;
197 }
198 auto rdm = ReminderDataManager::GetInstance();
199 if (rdm == nullptr) {
200 ANSR_LOGW("Reminder data manager not init!");
201 return ERR_NO_INIT;
202 }
203 return rdm->AddExcludeDate(reminderId, date, bundleOption);
204 }
205
DelExcludeDates(const int32_t reminderId)206 ErrCode AdvancedNotificationService::DelExcludeDates(const int32_t reminderId)
207 {
208 HITRACE_METER_NAME(HITRACE_TAG_OHOS, __PRETTY_FUNCTION__);
209 ANSR_LOGI("Del Exclude Dates");
210 std::string bundleName = GetClientBundleName();
211 if (!CheckReminderPermission()) {
212 ANSR_LOGW("Permission denied: ohos.permission.PUBLISH_AGENT_REMINDER");
213 return ERR_REMINDER_PERMISSION_DENIED;
214 }
215
216 sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
217 if (bundleOption == nullptr) {
218 ANSR_LOGW("Generate bundle option failed!");
219 return ERR_ANS_INVALID_BUNDLE;
220 }
221 auto rdm = ReminderDataManager::GetInstance();
222 if (rdm == nullptr) {
223 ANSR_LOGW("Reminder data manager not init!");
224 return ERR_NO_INIT;
225 }
226 return rdm->DelExcludeDates(reminderId, bundleOption);
227 }
228
GetExcludeDates(const int32_t reminderId,std::vector<uint64_t> & dates)229 ErrCode AdvancedNotificationService::GetExcludeDates(const int32_t reminderId, std::vector<uint64_t>& dates)
230 {
231 HITRACE_METER_NAME(HITRACE_TAG_OHOS, __PRETTY_FUNCTION__);
232 ANSR_LOGI("Get Exclude Dates");
233 std::string bundleName = GetClientBundleName();
234 if (!CheckReminderPermission()) {
235 ANSR_LOGW("Permission denied: ohos.permission.PUBLISH_AGENT_REMINDER");
236 return ERR_REMINDER_PERMISSION_DENIED;
237 }
238
239 sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
240 if (bundleOption == nullptr) {
241 ANSR_LOGW("Generate bundle option failed!");
242 return ERR_ANS_INVALID_BUNDLE;
243 }
244 auto rdm = ReminderDataManager::GetInstance();
245 if (rdm == nullptr) {
246 ANSR_LOGW("Reminder data manager not init!");
247 return ERR_NO_INIT;
248 }
249 return rdm->GetExcludeDates(reminderId, bundleOption, dates);
250 }
251
252 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
GetRemindType()253 NotificationConstant::RemindType AdvancedNotificationService::GetRemindType()
254 {
255 bool remind = localScreenOn_;
256 if (distributedReminderPolicy_ == NotificationConstant::DistributedReminderPolicy::DEFAULT) {
257 bool remoteUsing = false;
258 ErrCode result = DistributedScreenStatusManager::GetInstance()->CheckRemoteDevicesIsUsing(remoteUsing);
259 if (result != ERR_OK) {
260 remind = true;
261 }
262 if (!localScreenOn_ && !remoteUsing) {
263 remind = true;
264 }
265 } else if (distributedReminderPolicy_ == NotificationConstant::DistributedReminderPolicy::ALWAYS_REMIND) {
266 remind = true;
267 } else if (distributedReminderPolicy_ == NotificationConstant::DistributedReminderPolicy::DO_NOT_REMIND) {
268 remind = false;
269 }
270
271 if (localScreenOn_) {
272 if (remind) {
273 return NotificationConstant::RemindType::DEVICE_ACTIVE_REMIND;
274 } else {
275 return NotificationConstant::RemindType::DEVICE_ACTIVE_DONOT_REMIND;
276 }
277 } else {
278 if (remind) {
279 return NotificationConstant::RemindType::DEVICE_IDLE_REMIND;
280 } else {
281 return NotificationConstant::RemindType::DEVICE_IDLE_DONOT_REMIND;
282 }
283 }
284 }
285 #endif
286
GetDeviceRemindType(NotificationConstant::RemindType & remindType)287 ErrCode AdvancedNotificationService::GetDeviceRemindType(NotificationConstant::RemindType &remindType)
288 {
289 ANS_LOGD("%{public}s", __FUNCTION__);
290
291 bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
292 if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
293 return ERR_ANS_NON_SYSTEM_APP;
294 }
295
296 if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
297 return ERR_ANS_PERMISSION_DENIED;
298 }
299
300 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
301 if (notificationSvrQueue_ == nullptr) {
302 ANS_LOGE("Serial queue is invalid.");
303 return ERR_ANS_INVALID_PARAM;
304 }
305 ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() { remindType = GetRemindType(); }));
306 notificationSvrQueue_->wait(handler);
307 return ERR_OK;
308 #else
309 return ERR_INVALID_OPERATION;
310 #endif
311 }
312
SetNotificationRemindType(sptr<Notification> notification,bool isLocal)313 ErrCode AdvancedNotificationService::SetNotificationRemindType(sptr<Notification> notification, bool isLocal)
314 {
315 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
316 notification->SetRemindType(GetRemindType());
317 #else
318 notification->SetRemindType(NotificationConstant::RemindType::NONE);
319 #endif
320 return ERR_OK;
321 }
322 } // namespace Notification
323 } // namespace OHOS
324