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