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