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