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