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