• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-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 "disturb_manager.h"
17 
18 #include <functional>
19 #include <iomanip>
20 #include <sstream>
21 
22 #include "advanced_notification_service.h"
23 #include "notification_preferences.h"
24 #include "os_account_manager_helper.h"
25 
26 #include "../advanced_notification_inline.cpp"
27 
28 namespace OHOS {
29 namespace Notification {
30 constexpr int32_t HOURS_IN_ONE_DAY = 24;
31 
HandleSetDoNotDisturbDate(MessageParcel & data,MessageParcel & reply)32 ErrCode DisturbManager::HandleSetDoNotDisturbDate(MessageParcel &data, MessageParcel &reply)
33 {
34     sptr<NotificationDoNotDisturbDate> date = data.ReadParcelable<NotificationDoNotDisturbDate>();
35     if (date == nullptr) {
36         ANS_LOGE("[HandleSetDoNotDisturbDate] fail: read date failed.");
37         return ERR_ANS_PARCELABLE_FAILED;
38     }
39 
40     ErrCode result = SetDoNotDisturbDate(date);
41     if (!reply.WriteInt32(result)) {
42         ANS_LOGE("[HandleSetDoNotDisturbDate] fail: write result failed, ErrCode=%{public}d", result);
43         return ERR_ANS_PARCELABLE_FAILED;
44     }
45 
46     return ERR_OK;
47 }
HandleSetDoNotDisturbDateByUser(MessageParcel & data,MessageParcel & reply)48 ErrCode DisturbManager::HandleSetDoNotDisturbDateByUser(MessageParcel &data, MessageParcel &reply)
49 {
50     int32_t userId = SUBSCRIBE_USER_INIT;
51     if (!data.ReadInt32(userId)) {
52         ANS_LOGE("[HandleSetDoNotDisturbDateByUser] fail: read userId failed.");
53         return ERR_ANS_PARCELABLE_FAILED;
54     }
55 
56     sptr<NotificationDoNotDisturbDate> date = data.ReadParcelable<NotificationDoNotDisturbDate>();
57     if (date == nullptr) {
58         ANS_LOGE("[HandleSetDoNotDisturbDateByUser] fail: read date failed.");
59         return ERR_ANS_PARCELABLE_FAILED;
60     }
61 
62     ErrCode result = SetDoNotDisturbDateByUserSyncQueue(userId, date);
63     if (!reply.WriteInt32(result)) {
64         ANS_LOGE("[HandleSetDoNotDisturbDateByUser] fail: write result failed, ErrCode=%{public}d", result);
65         return ERR_ANS_PARCELABLE_FAILED;
66     }
67 
68     return ERR_OK;
69 }
70 
SetDoNotDisturbDate(const sptr<NotificationDoNotDisturbDate> & date)71 ErrCode DisturbManager::SetDoNotDisturbDate(const sptr<NotificationDoNotDisturbDate> &date)
72 {
73     ANS_LOGD("%{public}s", __FUNCTION__);
74 
75     int32_t userId = SUBSCRIBE_USER_INIT;
76     if (OsAccountManagerHelper::GetInstance().GetCurrentActiveUserId(userId) != ERR_OK) {
77         ANS_LOGW("No active user found!");
78         return ERR_ANS_GET_ACTIVE_USER_FAILED;
79     }
80 
81     return SetDoNotDisturbDateByUserSyncQueue(userId, date);
82 }
83 
SetDoNotDisturbDateByUserSyncQueue(const int32_t & userId,const sptr<NotificationDoNotDisturbDate> & date)84 ErrCode DisturbManager::SetDoNotDisturbDateByUserSyncQueue(const int32_t &userId,
85     const sptr<NotificationDoNotDisturbDate> &date)
86 {
87     ANS_LOGD("%{public}s enter, userId = %{public}d", __FUNCTION__, userId);
88     if (userId <= SUBSCRIBE_USER_INIT) {
89         ANS_LOGE("Input userId is invalidity.");
90         return ERR_ANS_INVALID_PARAM;
91     }
92 
93     if (date == nullptr) {
94         ANS_LOGE("Invalid date param");
95         return ERR_ANS_INVALID_PARAM;
96     }
97     int64_t beginDate = ResetSeconds(date->GetBeginDate());
98     int64_t endDate = ResetSeconds(date->GetEndDate());
99     switch (date->GetDoNotDisturbType()) {
100         case NotificationConstant::DoNotDisturbType::NONE:
101             beginDate = 0;
102             endDate = 0;
103             break;
104         case NotificationConstant::DoNotDisturbType::ONCE:
105             AdjustDateForDndTypeOnce(beginDate, endDate);
106             break;
107         case NotificationConstant::DoNotDisturbType::CLEARLY:
108             if (beginDate >= endDate) {
109                 return ERR_ANS_INVALID_PARAM;
110             }
111             break;
112         default:
113             break;
114     }
115     ANS_LOGD("Before set SetDoNotDisturbDate beginDate = %{public}" PRId64 ", endDate = %{public}" PRId64,
116              beginDate, endDate);
117     const sptr<NotificationDoNotDisturbDate> newConfig = new (std::nothrow) NotificationDoNotDisturbDate(
118         date->GetDoNotDisturbType(), beginDate, endDate);
119     if (newConfig == nullptr) {
120         ANS_LOGE("Failed to create NotificationDoNotDisturbDate instance");
121         return ERR_NO_MEMORY;
122     }
123 
124     sptr<NotificationBundleOption> bundleOption = AdvancedNotificationService::GenerateBundleOption();
125     if (bundleOption == nullptr) {
126         ANS_LOGE("Generate invalid bundle option!");
127         return ERR_ANS_INVALID_BUNDLE;
128     }
129     AdvancedNotificationService::GetInstance()->SubmitSyncTask(std::bind([&]() {
130         SetDoNotDisturbDateByUserInner(userId, newConfig);
131     }));
132     return ERR_OK;
133 }
134 
SetDoNotDisturbDateByUserInner(const int32_t & userId,const sptr<NotificationDoNotDisturbDate> & date)135 ErrCode DisturbManager::SetDoNotDisturbDateByUserInner(const int32_t &userId,
136     const sptr<NotificationDoNotDisturbDate> &date)
137 {
138     ANS_LOGD("ffrt enter!");
139     ErrCode result = NotificationPreferences::GetInstance()->SetDoNotDisturbDate(userId, date);
140     if (result == ERR_OK) {
141         NotificationSubscriberManager::GetInstance()->NotifyDoNotDisturbDateChanged(userId, date);
142     }
143     return result;
144 }
145 
AdjustDateForDndTypeOnce(int64_t & beginDate,int64_t & endDate)146 void DisturbManager::AdjustDateForDndTypeOnce(int64_t &beginDate, int64_t &endDate)
147 {
148     std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
149     time_t nowT = std::chrono::system_clock::to_time_t(now);
150     tm nowTm = GetLocalTime(nowT);
151 
152     auto beginDateMilliseconds = std::chrono::milliseconds(beginDate);
153     auto beginDateTimePoint =
154         std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>(beginDateMilliseconds);
155     time_t beginDateT = std::chrono::system_clock::to_time_t(beginDateTimePoint);
156     tm beginDateTm = GetLocalTime(beginDateT);
157 
158     auto endDateMilliseconds = std::chrono::milliseconds(endDate);
159     auto endDateTimePoint =
160         std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>(endDateMilliseconds);
161     time_t endDateT = std::chrono::system_clock::to_time_t(endDateTimePoint);
162     tm endDateTm = GetLocalTime(endDateT);
163 
164     tm todayBeginTm = nowTm;
165     todayBeginTm.tm_sec = 0;
166     todayBeginTm.tm_min = beginDateTm.tm_min;
167     todayBeginTm.tm_hour = beginDateTm.tm_hour;
168 
169     tm todayEndTm = nowTm;
170     todayEndTm.tm_sec = 0;
171     todayEndTm.tm_min = endDateTm.tm_min;
172     todayEndTm.tm_hour = endDateTm.tm_hour;
173 
174     time_t todayBeginT = mktime(&todayBeginTm);
175     if (todayBeginT == -1) {
176         return;
177     }
178     time_t todayEndT = mktime(&todayEndTm);
179     if (todayEndT == -1) {
180         return;
181     }
182 
183     auto newBeginTimePoint = std::chrono::system_clock::from_time_t(todayBeginT);
184     auto newEndTimePoint = std::chrono::system_clock::from_time_t(todayEndT);
185     if (newBeginTimePoint >= newEndTimePoint) {
186         newEndTimePoint += std::chrono::hours(HOURS_IN_ONE_DAY);
187     }
188 
189     if (newEndTimePoint < now) {
190         newBeginTimePoint += std::chrono::hours(HOURS_IN_ONE_DAY);
191         newEndTimePoint += std::chrono::hours(HOURS_IN_ONE_DAY);
192     }
193 
194     auto newBeginDuration = std::chrono::duration_cast<std::chrono::milliseconds>(newBeginTimePoint.time_since_epoch());
195     beginDate = newBeginDuration.count();
196 
197     auto newEndDuration = std::chrono::duration_cast<std::chrono::milliseconds>(newEndTimePoint.time_since_epoch());
198     endDate = newEndDuration.count();
199 }
200 
201 }  // namespace Notification
202 }  // namespace OHOS
203