1 /*
2 * Copyright (c) 2025 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 "ans_log_wrapper.h"
19 #include "ans_permission_def.h"
20 #include "access_token_helper.h"
21
22 #include "ipc_skeleton.h"
23
24 namespace OHOS {
25 namespace Notification {
26 constexpr int32_t RSS_UID = 3051;
27
IsContained(const std::vector<std::string> & vec,const std::string & target)28 inline bool IsContained(const std::vector<std::string> &vec, const std::string &target)
29 {
30 bool isContained = false;
31
32 auto iter = vec.begin();
33 while (iter != vec.end()) {
34 if (*iter == target) {
35 isContained = true;
36 break;
37 }
38 iter++;
39 }
40
41 return isContained;
42 }
43
GetActiveNotifications(std::vector<sptr<NotificationRequest>> & notifications,const std::string & instanceKey)44 ErrCode AdvancedNotificationService::GetActiveNotifications(
45 std::vector<sptr<NotificationRequest>> ¬ifications, const std::string &instanceKey)
46 {
47 ANS_LOGD("called");
48
49 sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
50 if (bundleOption == nullptr) {
51 return ERR_ANS_INVALID_BUNDLE;
52 }
53 bundleOption->SetAppInstanceKey(instanceKey);
54
55 if (notificationSvrQueue_ == nullptr) {
56 ANS_LOGE("null notificationSvrQueue");
57 return ERR_ANS_INVALID_PARAM;
58 }
59 ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
60 ANS_LOGD("called");
61 notifications.clear();
62 for (auto record : notificationList_) {
63 if ((record->bundleOption->GetBundleName() == bundleOption->GetBundleName()) &&
64 (record->bundleOption->GetUid() == bundleOption->GetUid()) &&
65 (record->notification->GetInstanceKey() == bundleOption->GetAppInstanceKey())) {
66 notifications.push_back(record->request);
67 }
68 }
69 }));
70 notificationSvrQueue_->wait(handler);
71 return ERR_OK;
72 }
73
GetActiveNotificationNums(uint64_t & num)74 ErrCode AdvancedNotificationService::GetActiveNotificationNums(uint64_t &num)
75 {
76 ANS_LOGD("called");
77
78 sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
79 if (bundleOption == nullptr) {
80 ANS_LOGE("null bundleOption");
81 return ERR_ANS_INVALID_BUNDLE;
82 }
83
84 if (notificationSvrQueue_ == nullptr) {
85 ANS_LOGE("null notificationSvrQueue");
86 return ERR_ANS_INVALID_PARAM;
87 }
88 ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
89 ANS_LOGD("called");
90 size_t count = 0;
91 for (auto record : notificationList_) {
92 if ((record->bundleOption->GetBundleName() == bundleOption->GetBundleName()) &&
93 (record->bundleOption->GetUid() == bundleOption->GetUid())) {
94 count += 1;
95 }
96 }
97 num = static_cast<uint64_t>(count);
98 }));
99 notificationSvrQueue_->wait(handler);
100 return ERR_OK;
101 }
102
GetAllActiveNotifications(std::vector<sptr<Notification>> & notifications)103 ErrCode AdvancedNotificationService::GetAllActiveNotifications(std::vector<sptr<Notification>> ¬ifications)
104 {
105 ANS_LOGD("called");
106
107 bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
108 if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
109 return ERR_ANS_NON_SYSTEM_APP;
110 }
111
112 int32_t callingUid = IPCSkeleton::GetCallingUid();
113 if (callingUid != RSS_UID && !AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
114 ANS_LOGE("AccessTokenHelper::CheckPermission failed.");
115 return ERR_ANS_PERMISSION_DENIED;
116 }
117
118 if (notificationSvrQueue_ == nullptr) {
119 ANS_LOGE("null notificationSvrQueue");
120 return ERR_ANS_INVALID_PARAM;
121 }
122 ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
123 ANS_LOGD("called");
124 notifications.clear();
125 for (auto record : notificationList_) {
126 if (record->notification != nullptr && record->notification->request_ != nullptr) {
127 notifications.push_back(record->notification);
128 }
129 }
130 }));
131 notificationSvrQueue_->wait(handler);
132 return ERR_OK;
133 }
134
GetAllNotificationsBySlotType(std::vector<sptr<Notification>> & notifications,int32_t slotTypeInt)135 ErrCode AdvancedNotificationService::GetAllNotificationsBySlotType(std::vector<sptr<Notification>> ¬ifications,
136 int32_t slotTypeInt)
137 {
138 ANS_LOGD("called");
139
140 NotificationConstant::SlotType slotType = static_cast<NotificationConstant::SlotType>(slotTypeInt);
141 bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
142 if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
143 return ERR_ANS_NON_SYSTEM_APP;
144 }
145
146 if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
147 ANS_LOGE("AccessTokenHelper::CheckPermission failed.");
148 return ERR_ANS_PERMISSION_DENIED;
149 }
150
151 if (notificationSvrQueue_ == nullptr) {
152 ANS_LOGE("null notificationSvrQueue");
153 return ERR_ANS_INVALID_PARAM;
154 }
155 ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
156 ANS_LOGD("called");
157 notifications.clear();
158 for (auto record : notificationList_) {
159 if (record->notification != nullptr && record->notification->request_ != nullptr &&
160 record->notification->request_->GetSlotType() == slotType) {
161 notifications.push_back(record->notification);
162 }
163 }
164 }));
165 notificationSvrQueue_->wait(handler);
166 return ERR_OK;
167 }
168
GetSpecialActiveNotifications(const std::vector<std::string> & key,std::vector<sptr<Notification>> & notifications)169 ErrCode AdvancedNotificationService::GetSpecialActiveNotifications(
170 const std::vector<std::string> &key, std::vector<sptr<Notification>> ¬ifications)
171 {
172 ANS_LOGD("called");
173
174 bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
175 if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
176 return ERR_ANS_NON_SYSTEM_APP;
177 }
178
179 if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
180 ANS_LOGE("Check permission is false.");
181 return ERR_ANS_PERMISSION_DENIED;
182 }
183
184 if (notificationSvrQueue_ == nullptr) {
185 ANS_LOGE("null notificationSvrQueue");
186 return ERR_ANS_INVALID_PARAM;
187 }
188 ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
189 ANS_LOGD("called");
190 for (auto record : notificationList_) {
191 if (IsContained(key, record->notification->GetKey())) {
192 notifications.push_back(record->notification);
193 }
194 }
195 }));
196 notificationSvrQueue_->wait(handler);
197 return ERR_OK;
198 }
199
GetActiveNotificationByFilter(const sptr<NotificationBundleOption> & bundleOption,int32_t notificationId,const std::string & label,int32_t userId,const std::vector<std::string> & extraInfoKeys,sptr<NotificationRequest> & request)200 ErrCode AdvancedNotificationService::GetActiveNotificationByFilter(
201 const sptr<NotificationBundleOption> &bundleOption, int32_t notificationId, const std::string &label,
202 int32_t userId, const std::vector<std::string> &extraInfoKeys, sptr<NotificationRequest> &request)
203 {
204 ANS_LOGD("called");
205 sptr<NotificationBundleOption> bundle = GenerateValidBundleOption(bundleOption);
206 if (bundle == nullptr && userId != -1 && !bundleOption->GetBundleName().empty()) {
207 bundle = new (std::nothrow) NotificationBundleOption(bundleOption->GetBundleName(), 0);
208 }
209 if (bundle == nullptr) {
210 return ERR_ANS_INVALID_BUNDLE;
211 }
212 // get other bundle notification need controller permission
213 if (bundle->GetUid() != IPCSkeleton::GetCallingUid()) {
214 ANS_LOGI_LIMIT("None-self call, uid: %{public}d, curUid: %{public}d.",
215 bundle->GetUid(), IPCSkeleton::GetCallingUid());
216 if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
217 ANS_LOGE("Get live view by filter failed because check permission is false.");
218 return ERR_ANS_PERMISSION_DENIED;
219 }
220 }
221
222 if (notificationSvrQueue_ == nullptr) {
223 ANS_LOGE("null notificationSvrQueue");
224 return ERR_ANS_INVALID_PARAM;
225 }
226
227 ErrCode result = ERR_ANS_NOTIFICATION_NOT_EXISTS;
228 ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
229 ANS_LOGD("called");
230
231 auto record = GetRecordFromNotificationList(
232 notificationId, bundle->GetUid(), label, bundle->GetBundleName(), userId);
233 if ((record == nullptr) || (!record->request->IsCommonLiveView())) {
234 return;
235 }
236 result = IsAllowedGetNotificationByFilter(record, bundle);
237 if (result != ERR_OK) {
238 return;
239 }
240
241 if (extraInfoKeys.empty()) {
242 // return all liveViewExtraInfo because no extraInfoKeys
243 request = record->request;
244 return;
245 }
246 // obtain extraInfo by extraInfoKeys
247 if (FillRequestByKeys(record->request, extraInfoKeys, request) != ERR_OK) {
248 return;
249 }
250 }));
251 notificationSvrQueue_->wait(handler);
252
253 return result;
254 }
255
GetNotificationRequestByHashCode(const std::string & hashCode,sptr<NotificationRequest> & notificationRequest)256 ErrCode AdvancedNotificationService::GetNotificationRequestByHashCode(
257 const std::string& hashCode, sptr<NotificationRequest>& notificationRequest)
258 {
259 bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
260 if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
261 return ERR_ANS_NON_SYSTEM_APP;
262 }
263
264 if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
265 ANS_LOGE("Check permission is false.");
266 return ERR_ANS_PERMISSION_DENIED;
267 }
268
269 if (notificationSvrQueue_ == nullptr) {
270 ANS_LOGE("null notificationSvrQueue");
271 return ERR_ANS_INVALID_PARAM;
272 }
273
274 ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
275 auto record = GetFromNotificationList(hashCode);
276 if (record != nullptr) {
277 notificationRequest = record->request;
278 }
279 }));
280 notificationSvrQueue_->wait(handler);
281 return ERR_OK;
282 }
283 } // Notification
284 } // OHOS