• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025-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 <functional>
19 #include <iomanip>
20 #include <sstream>
21 
22 #include "ans_const_define.h"
23 #include "ans_inner_errors.h"
24 #include "ans_log_wrapper.h"
25 #include "access_token_helper.h"
26 #include "ans_permission_def.h"
27 #include "bundle_manager_helper.h"
28 #include "notification_constant.h"
29 #include "errors.h"
30 #include "ipc_skeleton.h"
31 #include "os_account_manager.h"
32 #include "notification_bundle_option.h"
33 #include "notification_preferences.h"
34 #include "os_account_manager_helper.h"
35 #include "notification_do_not_disturb_date.h"
36 #include "notification_analytics_util.h"
37 #include "../advanced_notification_inline.cpp"
38 
39 namespace OHOS {
40 namespace Notification {
41 
GetDoNotDisturbDate(sptr<NotificationDoNotDisturbDate> & date)42 ErrCode AdvancedNotificationService::GetDoNotDisturbDate(sptr<NotificationDoNotDisturbDate> &date)
43 {
44     ANS_LOGD("%{public}s", __FUNCTION__);
45 
46     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
47     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
48         return ERR_ANS_NON_SYSTEM_APP;
49     }
50 
51     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
52         return ERR_ANS_PERMISSION_DENIED;
53     }
54 
55     int32_t userId = SUBSCRIBE_USER_INIT;
56     if (OsAccountManagerHelper::GetInstance().GetCurrentActiveUserId(userId) != ERR_OK) {
57         return ERR_ANS_GET_ACTIVE_USER_FAILED;
58     }
59 
60     return GetDoNotDisturbDateByUser(userId, date);
61 }
62 
GetDoNotDisturbDate(int32_t userId,sptr<NotificationDoNotDisturbDate> & date)63 ErrCode AdvancedNotificationService::GetDoNotDisturbDate(int32_t userId,
64     sptr<NotificationDoNotDisturbDate> &date)
65 {
66     ANS_LOGD("%{public}s", __FUNCTION__);
67 
68     if (userId <= SUBSCRIBE_USER_INIT) {
69         ANS_LOGE("Input userId is invalid.");
70         return ERR_ANS_INVALID_PARAM;
71     }
72 
73     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
74     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
75         return ERR_ANS_NON_SYSTEM_APP;
76     }
77 
78     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
79         return ERR_ANS_PERMISSION_DENIED;
80     }
81 
82     return GetDoNotDisturbDateByUser(userId, date);
83 }
84 
GetDoNotDisturbDateByUser(const int32_t & userId,sptr<NotificationDoNotDisturbDate> & date)85 ErrCode AdvancedNotificationService::GetDoNotDisturbDateByUser(const int32_t &userId,
86     sptr<NotificationDoNotDisturbDate> &date)
87 {
88     ErrCode result = ERR_OK;
89     if (notificationSvrQueue_ == nullptr) {
90         ANS_LOGE("Serial queue is invalid.");
91         return ERR_ANS_INVALID_PARAM;
92     }
93     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
94         ANS_LOGD("ffrt enter!");
95         sptr<NotificationDoNotDisturbDate> currentConfig = nullptr;
96         result = NotificationPreferences::GetInstance()->GetDoNotDisturbDate(userId, currentConfig);
97         if (result != ERR_OK) {
98             return;
99         }
100         int64_t now = GetCurrentTime();
101         switch (currentConfig->GetDoNotDisturbType()) {
102             case NotificationConstant::DoNotDisturbType::CLEARLY:
103             case NotificationConstant::DoNotDisturbType::ONCE:
104                 if (now >= currentConfig->GetEndDate()) {
105                     date = new (std::nothrow) NotificationDoNotDisturbDate(
106                         NotificationConstant::DoNotDisturbType::NONE, 0, 0);
107                     if (date == nullptr) {
108                         ANS_LOGE("Failed to create NotificationDoNotDisturbDate instance");
109                         return;
110                     }
111                     NotificationPreferences::GetInstance()->SetDoNotDisturbDate(userId, date);
112                     return;
113                 } else {
114                     date = currentConfig;
115                 }
116                 break;
117             default:
118                 date = currentConfig;
119                 break;
120         }
121     }));
122     notificationSvrQueue_->wait(handler);
123     return ERR_OK;
124 }
125 
SetDoNotDisturbDate(const sptr<NotificationDoNotDisturbDate> & date)126 ErrCode AdvancedNotificationService::SetDoNotDisturbDate(const sptr<NotificationDoNotDisturbDate> &date)
127 {
128     ANS_LOGD("%{public}s", __FUNCTION__);
129 
130     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
131     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
132         ANS_LOGW("Not system app!");
133         return ERR_ANS_NON_SYSTEM_APP;
134     }
135 
136     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
137         ANS_LOGW("Check permission denied!");
138         return ERR_ANS_PERMISSION_DENIED;
139     }
140 
141     int32_t userId = SUBSCRIBE_USER_INIT;
142     if (OsAccountManagerHelper::GetInstance().GetCurrentActiveUserId(userId) != ERR_OK) {
143         ANS_LOGW("No active user found!");
144         return ERR_ANS_GET_ACTIVE_USER_FAILED;
145     }
146 
147     return SetDoNotDisturbDateByUser(userId, date);
148 }
149 
SetDoNotDisturbDate(int32_t userId,const sptr<NotificationDoNotDisturbDate> & date)150 ErrCode AdvancedNotificationService::SetDoNotDisturbDate(int32_t userId,
151     const sptr<NotificationDoNotDisturbDate> &date)
152 {
153     ANS_LOGD("%{public}s", __FUNCTION__);
154 
155     HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_14, EventBranchId::BRANCH_16);
156     message.Message("userId:" + std::to_string(userId));
157     if (userId <= SUBSCRIBE_USER_INIT) {
158         ANS_LOGE("Input userId is invalidity.");
159         message.ErrorCode(ERR_ANS_INVALID_PARAM);
160         NotificationAnalyticsUtil::ReportModifyEvent(message);
161         return ERR_ANS_INVALID_PARAM;
162     }
163 
164     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
165     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
166         return ERR_ANS_NON_SYSTEM_APP;
167     }
168 
169     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
170         return ERR_ANS_PERMISSION_DENIED;
171     }
172 
173     return SetDoNotDisturbDateByUser(userId, date);
174 }
175 
SetDoNotDisturbDateByUser(const int32_t & userId,const sptr<NotificationDoNotDisturbDate> & date)176 ErrCode AdvancedNotificationService::SetDoNotDisturbDateByUser(const int32_t &userId,
177     const sptr<NotificationDoNotDisturbDate> &date)
178 {
179     ANS_LOGD("%{public}s enter, userId = %{public}d", __FUNCTION__, userId);
180     if (date == nullptr) {
181         ANS_LOGE("Invalid date param");
182         return ERR_ANS_INVALID_PARAM;
183     }
184 
185     ErrCode result = ERR_OK;
186 
187     int64_t beginDate = ResetSeconds(date->GetBeginDate());
188     int64_t endDate = ResetSeconds(date->GetEndDate());
189     switch (date->GetDoNotDisturbType()) {
190         case NotificationConstant::DoNotDisturbType::NONE:
191             beginDate = 0;
192             endDate = 0;
193             break;
194         case NotificationConstant::DoNotDisturbType::ONCE:
195             AdjustDateForDndTypeOnce(beginDate, endDate);
196             break;
197         case NotificationConstant::DoNotDisturbType::CLEARLY:
198             if (beginDate >= endDate) {
199                 return ERR_ANS_INVALID_PARAM;
200             }
201             break;
202         default:
203             break;
204     }
205     ANS_LOGD("Before set SetDoNotDisturbDate beginDate = %{public}" PRId64 ", endDate = %{public}" PRId64,
206              beginDate, endDate);
207     const sptr<NotificationDoNotDisturbDate> newConfig = new (std::nothrow) NotificationDoNotDisturbDate(
208         date->GetDoNotDisturbType(),
209         beginDate,
210         endDate
211     );
212     if (newConfig == nullptr) {
213         ANS_LOGE("Failed to create NotificationDoNotDisturbDate instance");
214         return ERR_NO_MEMORY;
215     }
216     std::string bundle = GetClientBundleName();
217 
218     sptr<NotificationBundleOption> bundleOption = GenerateBundleOption();
219     if (bundleOption == nullptr) {
220         ANS_LOGE("Generate invalid bundle option!");
221         return ERR_ANS_INVALID_BUNDLE;
222     }
223 
224     if (notificationSvrQueue_ == nullptr) {
225         ANS_LOGE("Serial queue is invalid.");
226         return ERR_ANS_INVALID_PARAM;
227     }
228     ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() {
229         ANS_LOGD("ffrt enter!");
230         result = NotificationPreferences::GetInstance()->SetDoNotDisturbDate(userId, newConfig);
231         if (result == ERR_OK) {
232             NotificationSubscriberManager::GetInstance()->NotifyDoNotDisturbDateChanged(userId, newConfig, bundle);
233         }
234     }));
235     notificationSvrQueue_->wait(handler);
236 
237     return ERR_OK;
238 }
239 
AddDoNotDisturbProfiles(const std::vector<sptr<NotificationDoNotDisturbProfile>> & profiles)240 ErrCode AdvancedNotificationService::AddDoNotDisturbProfiles(
241     const std::vector<sptr<NotificationDoNotDisturbProfile>> &profiles)
242 {
243     ANS_LOGD("Called.");
244     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
245     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
246         return ERR_ANS_NON_SYSTEM_APP;
247     }
248     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
249         return ERR_ANS_PERMISSION_DENIED;
250     }
251     if (notificationSvrQueue_ == nullptr) {
252         ANS_LOGE("Serial queue is invalid.");
253         return ERR_ANS_INVALID_PARAM;
254     }
255     int32_t userId = SUBSCRIBE_USER_INIT;
256     if (OsAccountManagerHelper::GetInstance().GetCurrentActiveUserId(userId) != ERR_OK) {
257         ANS_LOGW("No active user found.");
258         return ERR_ANS_GET_ACTIVE_USER_FAILED;
259     }
260     ffrt::task_handle handler =
261         notificationSvrQueue_->submit_h(std::bind([copyUserId = userId, copyProfiles = profiles]() {
262             ANS_LOGD("The ffrt enter.");
263             NotificationPreferences::GetInstance()->AddDoNotDisturbProfiles(copyUserId, copyProfiles);
264         }));
265     notificationSvrQueue_->wait(handler);
266     return ERR_OK;
267 }
268 
RemoveDoNotDisturbProfiles(const std::vector<sptr<NotificationDoNotDisturbProfile>> & profiles)269 ErrCode AdvancedNotificationService::RemoveDoNotDisturbProfiles(
270     const std::vector<sptr<NotificationDoNotDisturbProfile>> &profiles)
271 {
272     ANS_LOGD("Called.");
273     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
274     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
275         return ERR_ANS_NON_SYSTEM_APP;
276     }
277     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
278         return ERR_ANS_PERMISSION_DENIED;
279     }
280     if (notificationSvrQueue_ == nullptr) {
281         ANS_LOGE("Serial queue is invalid.");
282         return ERR_ANS_INVALID_PARAM;
283     }
284     int32_t userId = SUBSCRIBE_USER_INIT;
285     if (OsAccountManagerHelper::GetInstance().GetCurrentActiveUserId(userId) != ERR_OK) {
286         ANS_LOGW("No active user found.");
287         return ERR_ANS_GET_ACTIVE_USER_FAILED;
288     }
289     ffrt::task_handle handler =
290         notificationSvrQueue_->submit_h(std::bind([copyUserId = userId, copyProfiles = profiles]() {
291             ANS_LOGD("The ffrt enter.");
292             NotificationPreferences::GetInstance()->RemoveDoNotDisturbProfiles(copyUserId, copyProfiles);
293         }));
294     notificationSvrQueue_->wait(handler);
295     return ERR_OK;
296 }
297 
GetDoNotDisturbProfile(int64_t id,sptr<NotificationDoNotDisturbProfile> & profile)298 ErrCode AdvancedNotificationService::GetDoNotDisturbProfile(int64_t id, sptr<NotificationDoNotDisturbProfile> &profile)
299 {
300     ANS_LOGD("Called.");
301     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
302     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
303         return ERR_ANS_NON_SYSTEM_APP;
304     }
305     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
306         return ERR_ANS_PERMISSION_DENIED;
307     }
308     int32_t userId = SUBSCRIBE_USER_INIT;
309     if (OsAccountManagerHelper::GetInstance().GetCurrentActiveUserId(userId) != ERR_OK) {
310         ANS_LOGW("No active user found.");
311         return ERR_ANS_GET_ACTIVE_USER_FAILED;
312     }
313 
314     profile = new (std::nothrow) NotificationDoNotDisturbProfile();
315     ErrCode result = NotificationPreferences::GetInstance()->GetDoNotDisturbProfile(id, userId, profile);
316     if (result != ERR_OK) {
317         ANS_LOGE("profile failed id: %{public}s, userid: %{public}d", std::to_string(id).c_str(), userId);
318     }
319     return result;
320 }
321 
DoesSupportDoNotDisturbMode(bool & doesSupport)322 ErrCode AdvancedNotificationService::DoesSupportDoNotDisturbMode(bool &doesSupport)
323 {
324     ANS_LOGD("%{public}s", __FUNCTION__);
325 
326     bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
327     if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
328         return ERR_ANS_NON_SYSTEM_APP;
329     }
330 
331     if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
332         return ERR_ANS_PERMISSION_DENIED;
333     }
334 
335     doesSupport = SUPPORT_DO_NOT_DISTRUB;
336     return ERR_OK;
337 }
338 
339 }  // namespace Notification
340 }  // namespace OHOS