• 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 "errors.h"
19 #include "ans_log_wrapper.h"
20 #include "access_token_helper.h"
21 #include "notification_preferences.h"
22 #include "notification_analytics_util.h"
23 #include "badge_number_callback_data.h"
24 #include "advanced_notification_inline.h"
25 #include "notification_subscriber_manager.h"
26 #include "enabled_notification_callback_data.h"
27 
28 #include "ipc_skeleton.h"
29 
30 namespace OHOS {
31 namespace Notification {
32 
33 constexpr int32_t BADGE_NUM_LIMIT = 0;
34 
SetNotificationBadgeNum(int32_t num)35 ErrCode AdvancedNotificationService::SetNotificationBadgeNum(int32_t num)
36 {
37     ANS_LOGD("called");
38 
39     sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
40     if (bundleOption == nullptr) {
41         ANS_LOGD("null bundleOption");
42         return ERR_ANS_INVALID_BUNDLE;
43     }
44 
45     if (notificationSvrQueue_ == nullptr) {
46         ANS_LOGE("null notificationSvrQueue");
47         return ERR_ANS_INVALID_PARAM;
48     }
49     ErrCode result = ERR_OK;
50     ffrt::task_handle handler = notificationSvrQueue_->submit_h(
51         std::bind([&]() {
52             ANS_LOGD("called");
53             result = NotificationPreferences::GetInstance()->SetTotalBadgeNums(bundleOption, num);
54         }));
55     notificationSvrQueue_->wait(handler);
56     return result;
57 }
58 
SetShowBadgeEnabledForBundle(const sptr<NotificationBundleOption> & bundleOption,bool enabled)59 ErrCode AdvancedNotificationService::SetShowBadgeEnabledForBundle(
60     const sptr<NotificationBundleOption> &bundleOption, bool enabled)
61 {
62     HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_13, EventBranchId::BRANCH_0);
63     if (bundleOption == nullptr) {
64         ANS_LOGE("null bundleOption");
65         NotificationAnalyticsUtil::ReportModifyEvent(message.ErrorCode(ERR_ANS_INVALID_BUNDLE));
66         return ERR_ANS_INVALID_BUNDLE;
67     }
68 
69     message.Message(bundleOption->GetBundleName() + "_" + std::to_string(bundleOption->GetUid()) +
70         " en" + std::to_string(enabled));
71 
72     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
73     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
74         ANS_LOGE("IsSystemApp is false.");
75         message.ErrorCode(ERR_ANS_NON_SYSTEM_APP).BranchId(BRANCH_1);
76         NotificationAnalyticsUtil::ReportModifyEvent(message);
77         return ERR_ANS_NON_SYSTEM_APP;
78     }
79 
80     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
81         ANS_LOGE("Permission Denied.");
82         message.ErrorCode(ERR_ANS_PERMISSION_DENIED).BranchId(BRANCH_2);
83         NotificationAnalyticsUtil::ReportModifyEvent(message);
84         return ERR_ANS_PERMISSION_DENIED;
85     }
86 
87     sptr<NotificationBundleOption> bundle = GenerateValidBundleOption(bundleOption);
88     if (bundle == nullptr) {
89         ANS_LOGE("null bundle");
90         return ERR_ANS_INVALID_BUNDLE;
91     }
92 
93     if (notificationSvrQueue_ == nullptr) {
94         ANS_LOGE("null notificationSvrQueue");
95         return ERR_ANS_INVALID_PARAM;
96     }
97     ErrCode result = ERR_OK;
98     ffrt::task_handle handler = notificationSvrQueue_->submit_h(
99         std::bind([&]() {
100             ANS_LOGD("called");
101             result = NotificationPreferences::GetInstance()->SetShowBadge(bundle, enabled);
102             if (result == ERR_OK) {
103                 HandleBadgeEnabledChanged(bundle, enabled);
104             }
105         }));
106     notificationSvrQueue_->wait(handler);
107     ANS_LOGI("%{public}s_%{public}d, enabled: %{public}s, Set show badge enabled for bundle result: %{public}d",
108         bundleOption->GetBundleName().c_str(), bundleOption->GetUid(), std::to_string(enabled).c_str(), result);
109     message.ErrorCode(result).BranchId(BRANCH_3);
110     NotificationAnalyticsUtil::ReportModifyEvent(message);
111     return result;
112 }
113 
HandleBadgeEnabledChanged(const sptr<NotificationBundleOption> & bundleOption,bool enabled)114 void AdvancedNotificationService::HandleBadgeEnabledChanged(
115     const sptr<NotificationBundleOption> &bundleOption, bool enabled)
116 {
117     sptr<EnabledNotificationCallbackData> enabledData = new (std::nothrow)
118         EnabledNotificationCallbackData(bundleOption->GetBundleName(), bundleOption->GetUid(), enabled);
119     if (enabledData == nullptr) {
120         ANS_LOGE("null enabledData");
121         return;
122     }
123 
124     NotificationSubscriberManager::GetInstance()->NotifyBadgeEnabledChanged(enabledData);
125 }
126 
GetShowBadgeEnabledForBundle(const sptr<NotificationBundleOption> & bundleOption,bool & enabled)127 ErrCode AdvancedNotificationService::GetShowBadgeEnabledForBundle(
128     const sptr<NotificationBundleOption> &bundleOption, bool &enabled)
129 {
130     ANS_LOGD("called");
131 
132     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
133     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
134         ANS_LOGD("VerifyNativeToken is bogus.");
135         return ERR_ANS_NON_SYSTEM_APP;
136     }
137 
138     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
139         return ERR_ANS_PERMISSION_DENIED;
140     }
141 
142     sptr<NotificationBundleOption> bundle = GenerateValidBundleOption(bundleOption);
143     if (bundle == nullptr) {
144         ANS_LOGE("null bundle");
145         return ERR_ANS_INVALID_BUNDLE;
146     }
147 
148     if (notificationSvrQueue_ == nullptr) {
149         ANS_LOGE("null notificationSvrQueue");
150         return ERR_ANS_INVALID_PARAM;
151     }
152     ErrCode result = ERR_OK;
153     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
154         ANS_LOGD("called");
155         result = NotificationPreferences::GetInstance()->IsShowBadge(bundle, enabled);
156         if (result == ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST) {
157             result = ERR_OK;
158             enabled = true;
159         }
160     }));
161     notificationSvrQueue_->wait(handler);
162     return result;
163 }
164 
GetShowBadgeEnabled(bool & enabled)165 ErrCode AdvancedNotificationService::GetShowBadgeEnabled(bool &enabled)
166 {
167     ANS_LOGD("called");
168 
169     sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
170     if (bundleOption == nullptr) {
171         return ERR_ANS_INVALID_BUNDLE;
172     }
173 
174     if (notificationSvrQueue_ == nullptr) {
175         ANS_LOGE("null notificationSvrQueue");
176         return ERR_ANS_INVALID_PARAM;
177     }
178     ErrCode result = ERR_OK;
179     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
180         ANS_LOGD("called");
181         result = NotificationPreferences::GetInstance()->IsShowBadge(bundleOption, enabled);
182         if (result == ERR_ANS_PREFERENCES_NOTIFICATION_BUNDLE_NOT_EXIST) {
183             result = ERR_OK;
184             enabled = true;
185         }
186     }));
187     notificationSvrQueue_->wait(handler);
188     return result;
189 }
190 
SetBadgeNumber(int32_t badgeNumber,const std::string & instanceKey)191 ErrCode AdvancedNotificationService::SetBadgeNumber(int32_t badgeNumber, const std::string &instanceKey)
192 {
193     ANS_LOGD("called");
194     if (notificationSvrQueue_ == nullptr) {
195         ANS_LOGE("null notificationSvrQueue");
196         return ERR_ANS_INVALID_PARAM;
197     }
198     int32_t callingUid = IPCSkeleton::GetCallingUid();
199     std::string bundleName = GetClientBundleName();
200     ANS_LOGD("SetBadgeNumber receive instanceKey:%{public}s", instanceKey.c_str());
201     sptr<BadgeNumberCallbackData> badgeData = new (std::nothrow) BadgeNumberCallbackData(
202         bundleName, instanceKey, callingUid, badgeNumber);
203     if (badgeData == nullptr) {
204         ANS_LOGE("Null badgeData.");
205         return ERR_ANS_NO_MEMORY;
206     }
207 
208     ffrt::task_handle handler = notificationSvrQueue_->submit_h([badgeData]() {
209         ANS_LOGD("called");
210         NotificationSubscriberManager::GetInstance()->SetBadgeNumber(badgeData);
211     });
212 
213     return ERR_OK;
214 }
215 
SetBadgeNumberForDhByBundle(const sptr<NotificationBundleOption> & bundleOption,int32_t badgeNumber)216 ErrCode AdvancedNotificationService::SetBadgeNumberForDhByBundle(
217     const sptr<NotificationBundleOption> &bundleOption, int32_t badgeNumber)
218 {
219     if (bundleOption == nullptr) {
220         ANS_LOGE("null bundleOption");
221         return ERR_ANS_INVALID_PARAM;
222     }
223     if (bundleOption->GetBundleName().empty()) {
224         ANS_LOGE("SetBadgeNumberForDhByBundle Invalid bundle name.");
225         return ERR_ANS_INVALID_PARAM;
226     }
227     if (bundleOption->GetUid() <= DEFAULT_UID) {
228         ANS_LOGE("SetBadgeNumberForDhByBundle invalid uid");
229         return ERR_ANS_INVALID_PARAM;
230     }
231     if (badgeNumber < BADGE_NUM_LIMIT) {
232         ANS_LOGE("SetBadgeNumberForDhByBundle invalid badgeNumber");
233         return ERR_ANS_INVALID_PARAM;
234     }
235     ANS_LOGI("SetBadgeNumberForDhByBundle bundleName = %{public}s uid = %{public}d",
236         bundleOption->GetBundleName().c_str(), bundleOption->GetUid());
237     HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_7, EventBranchId::BRANCH_6);
238     message.Message(bundleOption->GetBundleName() + "_" +std::to_string(bundleOption->GetUid()) +
239         " badgeNumber: " + std::to_string(badgeNumber));
240 
241     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
242     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
243         message.ErrorCode(ERR_ANS_NON_SYSTEM_APP).Append(" Not system app.");
244         NotificationAnalyticsUtil::ReportModifyEvent(message);
245         ANS_LOGE("Not system app.");
246         return ERR_ANS_NON_SYSTEM_APP;
247     }
248 
249     if (notificationSvrQueue_ == nullptr) {
250         return ERR_ANS_INVALID_PARAM;
251     }
252 
253     sptr<BadgeNumberCallbackData> badgeData = new (std::nothrow) BadgeNumberCallbackData(
254             bundleOption->GetBundleName(), bundleOption->GetUid(), badgeNumber);
255     if (badgeData == nullptr) {
256         ANS_LOGE("Null badgeData.");
257         return ERR_ANS_NO_MEMORY;
258     }
259 
260     ffrt::task_handle handler = notificationSvrQueue_->submit_h([badgeData]() {
261         ANS_LOGD("called");
262         NotificationSubscriberManager::GetInstance()->SetBadgeNumber(badgeData);
263     });
264 
265     return ERR_OK;
266 }
267 
SetBadgeNumberByBundle(const sptr<NotificationBundleOption> & bundleOption,int32_t badgeNumber)268 ErrCode AdvancedNotificationService::SetBadgeNumberByBundle(
269     const sptr<NotificationBundleOption> &bundleOption, int32_t badgeNumber)
270 {
271     if (bundleOption == nullptr || bundleOption->GetBundleName().empty()) {
272         return ERR_ANS_INVALID_PARAM;
273     }
274     HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_7, EventBranchId::BRANCH_6);
275     message.Message(bundleOption->GetBundleName() + "_" +std::to_string(bundleOption->GetUid()) +
276         " badgeNumber: " + std::to_string(badgeNumber));
277 
278     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
279     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
280         message.ErrorCode(ERR_ANS_NON_SYSTEM_APP).Append(" Not system app.");
281         NotificationAnalyticsUtil::ReportModifyEvent(message);
282         ANS_LOGE("Not system app.");
283         return ERR_ANS_NON_SYSTEM_APP;
284     }
285 
286     sptr<NotificationBundleOption> bundle = bundleOption;
287     ErrCode result = CheckBundleOptionValid(bundle);
288     if (result != ERR_OK) {
289         ANS_LOGE("Bundle is invalid.");
290         return result;
291     }
292 
293     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_AGENT_CONTROLLER)) {
294         std::string bundleName = GetClientBundleName();
295         if (bundleName.empty()) {
296             ANS_LOGE("Failed to get client bundle name.");
297             return result;
298         }
299         bool isAgent = false;
300         isAgent = IsAgentRelationship(bundleName, bundle->GetBundleName());
301         if (!isAgent) {
302             message.ErrorCode(ERR_ANS_NO_AGENT_SETTING).Append(" No agent setting.");
303             NotificationAnalyticsUtil::ReportModifyEvent(message);
304             ANS_LOGE("No agent setting.");
305             return ERR_ANS_NO_AGENT_SETTING;
306         }
307     }
308 
309     if (notificationSvrQueue_ == nullptr) {
310         return ERR_ANS_INVALID_PARAM;
311     }
312 
313     sptr<BadgeNumberCallbackData> badgeData = new (std::nothrow) BadgeNumberCallbackData(
314             bundle->GetBundleName(), bundle->GetUid(), badgeNumber);
315     if (badgeData == nullptr) {
316         ANS_LOGE("Null badgeData.");
317         return ERR_ANS_NO_MEMORY;
318     }
319 
320     ffrt::task_handle handler = notificationSvrQueue_->submit_h([badgeData]() {
321         ANS_LOGD("called");
322         NotificationSubscriberManager::GetInstance()->SetBadgeNumber(badgeData);
323     });
324 
325     return ERR_OK;
326 }
327 } // Notification
328 } // OHOS