• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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