• 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 "dark_mode_temp_state_manager.h"
17 
18 #include <ctime>
19 #include <sys/time.h>
20 #include <cinttypes>
21 #include "dark_mode_manager.h"
22 #include "parameter_wrap.h"
23 #include "ui_appearance_log.h"
24 
25 namespace OHOS::ArkUi::UiAppearance {
26 namespace {
27 static const std::string TEMPORARY_COLOR_MODE_PARAM_STRING = "persist.uiAppearance.dark_mode_temp_state_flag.";
28 static const std::string TEMPORARY_STATE_START_TIME_PARAM_STRING =
29     "persist.uiAppearance.dark_mode_temp_state_start_time.";
30 static const std::string TEMPORARY_STATE_END_TIME_PARAM_STRING = "persist.uiAppearance.dark_mode_temp_state_end_time.";
31 static const std::string TEMPORARY_COLOR_MODE_TEMPORARY_STRING = "1";
32 static const std::string TEMPORARY_COLOR_MODE_NORMAL_STRING = "0";
33 constexpr int32_t DAY_TO_MINUTE = 24 * 60;
34 constexpr int32_t HOUR_TO_MINUTE = 60;
35 constexpr int32_t MINUTE_TO_SECOND = 60;
36 } // namespace
37 
InitData(const int32_t userId)38 void TemporaryColorModeManager::InitData(const int32_t userId)
39 {
40     TempColorModeInfo info;
41     std::string temporaryColorModeValue = TEMPORARY_COLOR_MODE_NORMAL_STRING;
42     GetParameterWrap(TemporaryColorModeAssignUser(userId), temporaryColorModeValue);
43     info.tempColorMode = temporaryColorModeValue == TEMPORARY_COLOR_MODE_NORMAL_STRING
44                                 ? TempColorModeType::ColorModeNormal
45                                 : TempColorModeType::ColorModeTemp;
46     if (info.tempColorMode == TempColorModeType::ColorModeTemp) {
47         std::string startTime = "0";
48         GetParameterWrap(TemporaryStateStartTimeAssignUser(userId), startTime);
49         info.keepTemporaryStateStartTime = atoll(startTime.c_str());
50 
51         std::string endTime = "0";
52         GetParameterWrap(TemporaryStateEndTimeAssignUser(userId), endTime);
53         info.keepTemporaryStateEndTime = atoll(endTime.c_str());
54     }
55     {
56         std::lock_guard guard(multiUserTempColorModeMapMutex_);
57         multiUserTempColorModeMap_[userId] = info;
58     }
59     LOGI("init temp colormode info userId:%{public}d, tempColorMode:%{public}d, keepStartTime:%{public}" PRId64
60          ", keepEndTime:%{public}" PRId64,
61         userId, static_cast<int32_t>(info.tempColorMode), info.keepTemporaryStateStartTime,
62         info.keepTemporaryStateEndTime);
63 }
64 
IsColorModeTemporary(const int32_t userId)65 bool TemporaryColorModeManager::IsColorModeTemporary(const int32_t userId)
66 {
67     std::lock_guard guard(multiUserTempColorModeMapMutex_);
68     auto it = multiUserTempColorModeMap_.find(userId);
69     if (it != multiUserTempColorModeMap_.end()) {
70         return it->second.tempColorMode == TempColorModeType::ColorModeTemp;
71     }
72     return false;
73 }
IsColorModeNormal(const int32_t userId)74 bool TemporaryColorModeManager::IsColorModeNormal(const int32_t userId)
75 {
76     std::lock_guard guard(multiUserTempColorModeMapMutex_);
77     auto it = multiUserTempColorModeMap_.find(userId);
78     if (it != multiUserTempColorModeMap_.end()) {
79         return it->second.tempColorMode == TempColorModeType::ColorModeNormal;
80     }
81     return true;
82 }
SetColorModeTemporary(const int32_t userId)83 bool TemporaryColorModeManager::SetColorModeTemporary(const int32_t userId)
84 {
85     {
86         std::lock_guard guard(multiUserTempColorModeMapMutex_);
87         multiUserTempColorModeMap_[userId].tempColorMode = TempColorModeType::ColorModeTemp;
88         int32_t settingStartTime = 0;
89         int32_t settingEndTime = 0;
90         auto res = DarkModeManager::GetInstance().GetSettingTime(userId, settingStartTime, settingEndTime);
91         if (res == false) {
92             LOGE("GetSettingTime faild userId: %{public}d", userId);
93             return false;
94         }
95         GetTempColorModeTimeInfo(settingStartTime, settingEndTime,
96             multiUserTempColorModeMap_[userId].keepTemporaryStateStartTime,
97             multiUserTempColorModeMap_[userId].keepTemporaryStateEndTime);
98     }
99     SaveTempColorModeInfo(userId);
100     return true;
101 }
SetColorModeNormal(const int32_t userId)102 bool TemporaryColorModeManager::SetColorModeNormal(const int32_t userId)
103 {
104     {
105         std::lock_guard guard(multiUserTempColorModeMapMutex_);
106         multiUserTempColorModeMap_[userId].tempColorMode = TempColorModeType::ColorModeNormal;
107         multiUserTempColorModeMap_[userId].keepTemporaryStateStartTime = 0;
108         multiUserTempColorModeMap_[userId].keepTemporaryStateEndTime = 0;
109     }
110     SaveTempColorModeInfo(userId);
111     return true;
112 }
113 
CheckTemporaryStateEffective(const int32_t userId)114 bool TemporaryColorModeManager::CheckTemporaryStateEffective(const int32_t userId)
115 {
116     auto checkTempStateNoTimeout = [](const int64_t startTime, const int64_t endTime) {
117         std::time_t timestampNow = std::time(nullptr);
118         if (timestampNow == static_cast<std::time_t>(-1)) {
119             LOGE("fail to get timestamp");
120             return false;
121         }
122         if (startTime < timestampNow && timestampNow < endTime) {
123             return true;
124         }
125         return false;
126     };
127 
128     std::lock_guard guard(multiUserTempColorModeMapMutex_);
129     auto it = multiUserTempColorModeMap_.find(userId);
130     if (it != multiUserTempColorModeMap_.end()) {
131         if (it->second.tempColorMode == TempColorModeType::ColorModeTemp &&
132             checkTempStateNoTimeout(it->second.keepTemporaryStateStartTime, it->second.keepTemporaryStateEndTime)) {
133             return true;
134         }
135     }
136     return false;
137 }
138 
TemporaryColorModeAssignUser(const int32_t userId)139 std::string TemporaryColorModeManager::TemporaryColorModeAssignUser(const int32_t userId)
140 {
141     return TEMPORARY_COLOR_MODE_PARAM_STRING + std::to_string(userId);
142 }
143 
TemporaryStateStartTimeAssignUser(const int32_t userId)144 std::string TemporaryColorModeManager::TemporaryStateStartTimeAssignUser(const int32_t userId)
145 {
146     return TEMPORARY_STATE_START_TIME_PARAM_STRING + std::to_string(userId);
147 }
148 
TemporaryStateEndTimeAssignUser(const int32_t userId)149 std::string TemporaryColorModeManager::TemporaryStateEndTimeAssignUser(const int32_t userId)
150 {
151     return TEMPORARY_STATE_END_TIME_PARAM_STRING + std::to_string(userId);
152 }
153 
GetTempColorModeTimeInfo(const int32_t settingStartTime,const int32_t settingEndTime,int64_t & tempStateStartTime,int64_t & tempStateEndTime)154 void TemporaryColorModeManager::GetTempColorModeTimeInfo(const int32_t settingStartTime,
155     const int32_t settingEndTime, int64_t& tempStateStartTime, int64_t& tempStateEndTime)
156 {
157     auto calcEndTimestamp = [](const int32_t secondOffset, int64_t& endTimeStamp) {
158         std::time_t timestamp = std::time(nullptr);
159         if (timestamp == static_cast<std::time_t>(-1)) {
160             LOGE("fail to get timestamp");
161             return false;
162         }
163         std::tm* nowTime = std::localtime(&timestamp);
164         if (nowTime != nullptr) {
165             nowTime->tm_hour = 0;
166             nowTime->tm_min = 0;
167             nowTime->tm_sec = 0;
168         }
169         std::time_t midnightTime = std::mktime(nowTime);
170         endTimeStamp = midnightTime + secondOffset - 1;
171         return true;
172     };
173 
174     tempStateStartTime = static_cast<int64_t>(std::time(nullptr));
175 
176     if (settingEndTime > DAY_TO_MINUTE) {
177         if (AlarmTimerManager::IsWithinTimeInterval(settingStartTime, settingEndTime) == false) {
178             /*********************************************************************
179             for example settingStartTime=20, settingEndTime=8
180                         ↓(setting)
181             xxxxxxxxx           xxxxxxxxxxxxxxxxxxxxxxxxxxxx            xxxxxxxxxx
182             0		8			20			24(0)			8		   20       24
183                         |-----------------------------------|
184             ************************************************************************/
185             calcEndTimestamp((settingEndTime * MINUTE_TO_SECOND), tempStateEndTime);
186         } else if (TemporaryColorModeManager::IsWithInPreInterval(settingStartTime, settingEndTime)) {
187             /*********************************************************************
188             for example settingStartTime=20, settingEndTime=8
189               ↓(setting)
190             xxxxxxxxx           xxxxxxxxxxxxxxxxxxxxxxxxxxxx            xxxxxxxxxx
191             0		8			20			24(0)			8		   20       24
192               |-----------------|
193             ************************************************************************/
194             calcEndTimestamp((settingStartTime * MINUTE_TO_SECOND), tempStateEndTime);
195         } else {
196             /*********************************************************************
197             for example settingStartTime=20, settingEndTime=8
198                                        ↓(setting)
199             xxxxxxxxx           xxxxxxxxxxxxxxxxxxxxxxxxxxxx            xxxxxxxxxx
200             0		8			20			24(0)			8		   20       24
201                                        |-------------------------------|
202             ************************************************************************/
203             calcEndTimestamp(((settingStartTime + DAY_TO_MINUTE) * MINUTE_TO_SECOND), tempStateEndTime);
204         }
205     } else {
206         if (AlarmTimerManager::IsWithinTimeInterval(settingStartTime, settingEndTime)) {
207             /*********************************************************************
208             for example settingStartTime=11, settingEndTime=16
209                         ↓(setting)
210                     xxxxxxxxxx                              xxxxxxxxxxxx
211             0		11		16				24(0)			11		   16       24
212                         |-----------------------------------|
213             ************************************************************************/
214             calcEndTimestamp(((settingStartTime + DAY_TO_MINUTE) * MINUTE_TO_SECOND), tempStateEndTime);
215         } else if (TemporaryColorModeManager::IsWithInPreInterval(settingStartTime, settingEndTime)) {
216             /*********************************************************************
217             for example settingStartTime=11, settingEndTime=16
218                ↓(setting)
219                     xxxxxxxxxx                              xxxxxxxxxxxx
220             0		11		16				24(0)			11		   16       24
221                |-------------|
222             ************************************************************************/
223             calcEndTimestamp((settingEndTime * MINUTE_TO_SECOND), tempStateEndTime);
224         } else {
225             /*********************************************************************
226             for example settingStartTime=11, settingEndTime=16
227                                   ↓(setting)
228                     xxxxxxxxxx                              xxxxxxxxxxxx
229             0		11		16				24(0)			11		   16       24
230                                   |-------------------------------------|
231             ************************************************************************/
232             calcEndTimestamp(((settingEndTime + DAY_TO_MINUTE) * MINUTE_TO_SECOND), tempStateEndTime);
233         }
234     }
235 }
236 
IsWithInPreInterval(const int32_t startTime,const int32_t endTime)237 bool TemporaryColorModeManager::IsWithInPreInterval(const int32_t startTime, const int32_t endTime)
238 {
239     std::time_t timestamp = std::time(nullptr);
240     if (timestamp == static_cast<std::time_t>(-1)) {
241         LOGE("fail to get timestamp");
242         return false;
243     }
244     std::tm* nowTime = std::localtime(&timestamp);
245     int32_t totalMinutes { 0 };
246     if (nowTime != nullptr) {
247         totalMinutes = static_cast<int32_t>(nowTime->tm_hour * HOUR_TO_MINUTE + nowTime->tm_min);
248     }
249 
250     if (totalMinutes <= startTime) {
251         return true;
252     }
253     return false;
254 }
255 
SaveTempColorModeInfo(const int32_t userId)256 void TemporaryColorModeManager::SaveTempColorModeInfo(const int32_t userId)
257 {
258     TempColorModeInfo info;
259     {
260         std::lock_guard guard(multiUserTempColorModeMapMutex_);
261         info = multiUserTempColorModeMap_[userId];
262     }
263     SetParameterWrap(TemporaryColorModeAssignUser(userId), info.tempColorMode == TempColorModeType::ColorModeNormal
264                                                                ? TEMPORARY_COLOR_MODE_NORMAL_STRING
265                                                                : TEMPORARY_COLOR_MODE_TEMPORARY_STRING);
266     LOGI("SaveTempColorModeInfo userId:%{public}d,colorMode:%{public}d", userId,
267         static_cast<int32_t>(info.tempColorMode));
268     if (info.tempColorMode == TempColorModeType::ColorModeTemp) {
269         SetParameterWrap(TemporaryStateStartTimeAssignUser(userId), std::to_string(info.keepTemporaryStateStartTime));
270         SetParameterWrap(TemporaryStateEndTimeAssignUser(userId), std::to_string(info.keepTemporaryStateEndTime));
271         LOGI("SaveTempColorModeInfo keepStartTime:%{public}" PRId64 ",keepEndTime:%{public}" PRId64,
272             info.keepTemporaryStateStartTime, info.keepTemporaryStateEndTime);
273     }
274 }
275 
276 } // namespace OHOS::ArkUi::UiAppearance
277