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 "notification_constant.h"
29 #include "notification_request.h"
30 #include "os_account_manager.h"
31 #include "hitrace_meter_adapter.h"
32 #include "reminder_data_manager.h"
33 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
34 #include "distributed_notification_manager.h"
35 #include "distributed_preferences.h"
36 #include "distributed_screen_status_manager.h"
37 #endif
38
39 #include "advanced_notification_inline.cpp"
40
41 namespace OHOS {
42 namespace Notification {
CheckReminderPermission()43 inline bool AdvancedNotificationService::CheckReminderPermission()
44 {
45 Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
46 ErrCode result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(
47 callerToken, "ohos.permission.PUBLISH_AGENT_REMINDER");
48 return result == Security::AccessToken::PermissionState::PERMISSION_GRANTED;
49 }
50
PublishReminder(sptr<ReminderRequest> & reminder)51 ErrCode AdvancedNotificationService::PublishReminder(sptr<ReminderRequest> &reminder)
52 {
53 ANSR_LOGI("Publish reminder");
54 if (!reminder) {
55 ANSR_LOGE("ReminderRequest object is nullptr");
56 return ERR_ANS_INVALID_PARAM;
57 }
58
59 if (!CheckReminderPermission()) {
60 ANSR_LOGW("Permission denied: ohos.permission.PUBLISH_AGENT_REMINDER");
61 return ERR_REMINDER_PERMISSION_DENIED;
62 }
63
64 sptr<NotificationRequest> notificationRequest = reminder->GetNotificationRequest();
65 std::string bundle = GetClientBundleName();
66 reminder->InitCreatorBundleName(bundle);
67 if (reminder->GetWantAgentInfo() == nullptr || reminder->GetMaxScreenWantAgentInfo() == nullptr) {
68 ANSR_LOGE("wantagent info is nullptr");
69 return ERR_ANS_INVALID_PARAM;
70 }
71 std::string wantAgentName = reminder->GetWantAgentInfo()->pkgName;
72 std::string msWantAgentName = reminder->GetMaxScreenWantAgentInfo()->pkgName;
73 if (wantAgentName != msWantAgentName && wantAgentName != "" && msWantAgentName != "") {
74 ANSR_LOGE("wantAgentName is not same to msWantAgentName, wantAgentName:%{public}s, msWantAgentName:%{public}s",
75 wantAgentName.c_str(), msWantAgentName.c_str());
76 return ERR_ANS_INVALID_PARAM;
77 }
78 if (wantAgentName != bundle && wantAgentName != "") {
79 ANSR_LOGI("Set agent reminder, bundle:%{public}s, wantAgentName:%{public}s", bundle.c_str(),
80 wantAgentName.c_str());
81 SetAgentNotification(notificationRequest, wantAgentName);
82 } else if (msWantAgentName != bundle && msWantAgentName != "") {
83 ANSR_LOGI("Set agent reminder, bundle:%{public}s, msWantAgentName:%{public}s", bundle.c_str(),
84 msWantAgentName.c_str());
85 SetAgentNotification(notificationRequest, msWantAgentName);
86 }
87 sptr<NotificationBundleOption> bundleOption = nullptr;
88 ErrCode result = PrepareNotificationInfo(notificationRequest, bundleOption);
89 if (result != ERR_OK) {
90 ANSR_LOGW("PrepareNotificationInfo fail");
91 return result;
92 }
93 bool allowedNotify = false;
94 result = IsAllowedNotifySelf(bundleOption, allowedNotify);
95 if (!reminder->IsSystemApp() && (result != ERR_OK || !allowedNotify)) {
96 ANSR_LOGW("The application does not request enable notification");
97 return ERR_REMINDER_NOTIFICATION_NOT_ENABLE;
98 }
99 auto rdm = ReminderDataManager::GetInstance();
100 if (rdm == nullptr) {
101 return ERR_NO_INIT;
102 }
103 return rdm->PublishReminder(reminder, bundleOption);
104 }
105
CancelReminder(const int32_t reminderId)106 ErrCode AdvancedNotificationService::CancelReminder(const int32_t reminderId)
107 {
108 ANSR_LOGI("Cancel Reminder");
109 if (!CheckReminderPermission()) {
110 ANSR_LOGW("Permission denied: ohos.permission.PUBLISH_AGENT_REMINDER");
111 return ERR_REMINDER_PERMISSION_DENIED;
112 }
113
114 sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
115 if (bundleOption == nullptr) {
116 return ERR_ANS_INVALID_BUNDLE;
117 }
118 auto rdm = ReminderDataManager::GetInstance();
119 if (rdm == nullptr) {
120 return ERR_NO_INIT;
121 }
122 return rdm->CancelReminder(reminderId, bundleOption);
123 }
124
CancelAllReminders()125 ErrCode AdvancedNotificationService::CancelAllReminders()
126 {
127 ANSR_LOGI("Cancel all reminders");
128 if (!CheckReminderPermission()) {
129 ANSR_LOGW("Permission denied: ohos.permission.PUBLISH_AGENT_REMINDER");
130 return ERR_REMINDER_PERMISSION_DENIED;
131 }
132
133 sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
134 if (bundleOption == nullptr) {
135 return ERR_ANS_INVALID_BUNDLE;
136 }
137 int32_t userId = -1;
138 AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(bundleOption->GetUid(), userId);
139 auto rdm = ReminderDataManager::GetInstance();
140 if (rdm == nullptr) {
141 return ERR_NO_INIT;
142 }
143 return rdm->CancelAllReminders(bundleOption->GetBundleName(), userId);
144 }
145
146
GetValidReminders(std::vector<sptr<ReminderRequest>> & reminders)147 ErrCode AdvancedNotificationService::GetValidReminders(std::vector<sptr<ReminderRequest>> &reminders)
148 {
149 ANSR_LOGI("GetValidReminders");
150 if (!CheckReminderPermission()) {
151 ANSR_LOGW("Permission denied: ohos.permission.PUBLISH_AGENT_REMINDER");
152 return ERR_REMINDER_PERMISSION_DENIED;
153 }
154
155 reminders.clear();
156 sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
157 if (bundleOption == nullptr) {
158 return ERR_ANS_INVALID_BUNDLE;
159 }
160 auto rdm = ReminderDataManager::GetInstance();
161 if (rdm == nullptr) {
162 return ERR_NO_INIT;
163 }
164 rdm->GetValidReminders(bundleOption, reminders);
165 ANSR_LOGD("Valid reminders size=%{public}zu", reminders.size());
166 return ERR_OK;
167 }
168
169 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
GetRemindType()170 NotificationConstant::RemindType AdvancedNotificationService::GetRemindType()
171 {
172 bool remind = localScreenOn_;
173 if (distributedReminderPolicy_ == NotificationConstant::DistributedReminderPolicy::DEFAULT) {
174 bool remoteUsing = false;
175 ErrCode result = DistributedScreenStatusManager::GetInstance()->CheckRemoteDevicesIsUsing(remoteUsing);
176 if (result != ERR_OK) {
177 remind = true;
178 }
179 if (!localScreenOn_ && !remoteUsing) {
180 remind = true;
181 }
182 } else if (distributedReminderPolicy_ == NotificationConstant::DistributedReminderPolicy::ALWAYS_REMIND) {
183 remind = true;
184 } else if (distributedReminderPolicy_ == NotificationConstant::DistributedReminderPolicy::DO_NOT_REMIND) {
185 remind = false;
186 }
187
188 if (localScreenOn_) {
189 if (remind) {
190 return NotificationConstant::RemindType::DEVICE_ACTIVE_REMIND;
191 } else {
192 return NotificationConstant::RemindType::DEVICE_ACTIVE_DONOT_REMIND;
193 }
194 } else {
195 if (remind) {
196 return NotificationConstant::RemindType::DEVICE_IDLE_REMIND;
197 } else {
198 return NotificationConstant::RemindType::DEVICE_IDLE_DONOT_REMIND;
199 }
200 }
201 }
202 #endif
203
GetDeviceRemindType(NotificationConstant::RemindType & remindType)204 ErrCode AdvancedNotificationService::GetDeviceRemindType(NotificationConstant::RemindType &remindType)
205 {
206 ANS_LOGD("%{public}s", __FUNCTION__);
207
208 bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
209 if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
210 return ERR_ANS_NON_SYSTEM_APP;
211 }
212
213 if (!CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
214 return ERR_ANS_PERMISSION_DENIED;
215 }
216
217 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
218 if (notificationSvrQueue_ == nullptr) {
219 ANS_LOGE("Serial queue is invalid.");
220 return ERR_ANS_INVALID_PARAM;
221 }
222 ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() { remindType = GetRemindType(); }));
223 notificationSvrQueue_->wait(handler);
224 return ERR_OK;
225 #else
226 return ERR_INVALID_OPERATION;
227 #endif
228 }
229
SetNotificationRemindType(sptr<Notification> notification,bool isLocal)230 ErrCode AdvancedNotificationService::SetNotificationRemindType(sptr<Notification> notification, bool isLocal)
231 {
232 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
233 notification->SetRemindType(GetRemindType());
234 #else
235 notification->SetRemindType(NotificationConstant::RemindType::NONE);
236 #endif
237 return ERR_OK;
238 }
239 } // namespace Notification
240 } // namespace OHOS
241