• 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 "dark_mode_manager.h"
17 
18 #include "setting_data_manager.h"
19 #include "ui_appearance_log.h"
20 
21 namespace OHOS::ArkUi::UiAppearance {
22 namespace {
23 const std::string SETTING_DARK_MODE_MODE = "settings.uiappearance.darkmode_mode";
24 const std::string SETTING_DARK_MODE_START_TIME = "settings.uiappearance.darkmode_starttime";
25 const std::string SETTING_DARK_MODE_END_TIME = "settings.uiappearance.darkmode_endtime";
26 const std::string SETTING_DARK_MODE_SUN_SET = "settings.display.sun_set";
27 const std::string SETTING_DARK_MODE_SUN_RISE = "settings.display.sun_rise";
28 const static int32_t USER100 = 100;
29 }
30 
GetInstance()31 DarkModeManager &DarkModeManager::GetInstance()
32 {
33     static DarkModeManager instance;
34     return instance;
35 }
36 
Initialize(const std::function<void (bool,int32_t)> & updateCallback)37 ErrCode DarkModeManager::Initialize(const std::function<void(bool, int32_t)>& updateCallback)
38 {
39     LoadSettingDataObserversCallback();
40     updateCallback_ = updateCallback;
41     return ERR_OK;
42 }
43 
LoadUserSettingData(const int32_t userId,const bool needUpdateCallback,bool & isDarkMode,const bool bootLoadFlag)44 ErrCode DarkModeManager::LoadUserSettingData(
45     const int32_t userId, const bool needUpdateCallback, bool &isDarkMode, const bool bootLoadFlag)
46 {
47     SettingDataManager& manager = SettingDataManager::GetInstance();
48     int32_t darkMode = DARK_MODE_INVALID;
49     manager.GetInt32ValueStrictly(SETTING_DARK_MODE_MODE, darkMode, userId);
50     if (darkMode < DARK_MODE_INVALID || darkMode >= DARK_MODE_SIZE) {
51         LOGE("dark mode out of range: %{public}d, userId: %{public}d", darkMode, userId);
52         darkMode = DARK_MODE_INVALID;
53     }
54     int32_t startTime = -1;
55     manager.GetInt32ValueStrictly(SETTING_DARK_MODE_START_TIME, startTime, userId);
56     int32_t endTime = -1;
57     manager.GetInt32ValueStrictly(SETTING_DARK_MODE_END_TIME, endTime, userId);
58     int32_t sunsetTime = SUNSET_TIME_DEFAULT;
59     manager.GetInt32ValueStrictly(SETTING_DARK_MODE_SUN_SET, sunsetTime, userId);
60     int32_t sunriseTime = SUNRISE_TIME_DEFAULT;
61     manager.GetInt32ValueStrictly(SETTING_DARK_MODE_SUN_RISE, sunriseTime, userId);
62 
63     std::lock_guard lock(darkModeStatesMutex_);
64     DarkModeState& state = darkModeStates_[userId];
65     state.settingMode = static_cast<DarkModeMode>(darkMode);
66     state.settingStartTime = startTime;
67     state.settingEndTime = endTime;
68     state.settingSunsetTime = sunsetTime;
69     state.settingSunriseTime = sunriseTime;
70     LOGI("load user setting data, userId: %{public}d, mode: %{public}d, start: %{public}d, end : %{public}d",
71         userId, darkMode, startTime, endTime);
72     temporaryColorModeMgr_.InitData(userId);
73     if (temporaryColorModeMgr_.IsColorModeTemporary(userId) &&
74         temporaryColorModeMgr_.CheckTemporaryStateEffective(userId) == false) {
75         temporaryColorModeMgr_.SetColorModeNormal(userId);
76     }
77     screenSwitchOperatorMgr_.ResetScreenOffOperateInfo();
78     return OnStateChangeLocked(userId, needUpdateCallback, isDarkMode, false, bootLoadFlag);
79 }
80 
NotifyDarkModeUpdate(const int32_t userId,const bool isDarkMode)81 void DarkModeManager::NotifyDarkModeUpdate(const int32_t userId, const bool isDarkMode)
82 {
83     SettingDataManager& manager = SettingDataManager::GetInstance();
84     std::lock_guard lock(darkModeStatesMutex_);
85     const DarkModeState& state = darkModeStates_[userId];
86     if (isDarkMode) {
87         if (state.settingMode == DARK_MODE_ALWAYS_LIGHT || state.settingMode == DARK_MODE_INVALID) {
88             LOGI("notify change to always dark, userId: %{public}d", userId);
89             manager.SetStringValue(SETTING_DARK_MODE_MODE, std::to_string(DARK_MODE_ALWAYS_DARK), userId);
90         } // else no need to change
91     } else {
92         if (state.settingMode == DARK_MODE_ALWAYS_DARK || state.settingMode == DARK_MODE_INVALID) {
93             LOGI("notify change to always light, userId: %{public}d", userId);
94             manager.SetStringValue(SETTING_DARK_MODE_MODE, std::to_string(DARK_MODE_ALWAYS_LIGHT), userId);
95         } // else no need to change
96     }
97 }
98 
ScreenOnCallback()99 void DarkModeManager::ScreenOnCallback()
100 {
101     screenSwitchOperatorMgr_.SetScreenOn();
102 }
103 
ScreenOffCallback()104 void DarkModeManager::ScreenOffCallback()
105 {
106     screenSwitchOperatorMgr_.SetScreenOff();
107     if (screenSwitchOperatorMgr_.HaveScreenOffOperate()) {
108         bool switchToDark = false;
109         int32_t userId = USER100;
110         screenSwitchOperatorMgr_.GetScreenOffOperateInfo(switchToDark, userId);
111         OnChangeDarkMode(
112             switchToDark == true ? DarkModeMode::DARK_MODE_ALWAYS_DARK : DarkModeMode::DARK_MODE_ALWAYS_LIGHT,
113             userId);
114         screenSwitchOperatorMgr_.ResetScreenOffOperateInfo();
115     }
116 }
117 
OnSwitchUser(const int32_t userId)118 ErrCode DarkModeManager::OnSwitchUser(const int32_t userId)
119 {
120     SettingDataManager& manager = SettingDataManager::GetInstance();
121     if (!manager.IsInitialized()) {
122         ErrCode code = manager.Initialize();
123         if (code != ERR_OK || manager.IsInitialized() == false) {
124             LOGE("setting data manager is not initialized");
125             return ERR_NO_INIT;
126         }
127     }
128 
129     if (userId <= INVALID_USER_ID) {
130         LOGE("invalid userId: %{public}d", userId);
131         return ERR_INVALID_OPERATION;
132     }
133 
134     std::lock_guard lock(settingDataObserversMutex_);
135     if (settingDataObserversUserId_ != INVALID_USER_ID) {
136         LOGI("clear timers and unregister observers for userId: %{public}d", settingDataObserversUserId_);
137         alarmTimerManager_.ClearTimerByUserId(settingDataObserversUserId_);
138         UnregisterSettingDataObserversLocked(settingDataObserversUserId_);
139         settingDataObserversUserId_ = INVALID_USER_ID;
140     }
141 
142     ErrCode code = RegisterSettingDataObserversLocked(userId);
143     settingDataObserversUserId_ = userId;
144     return code;
145 }
146 
DoSwitchTemporaryColorMode(const int32_t userId,bool isDarkMode)147 void DarkModeManager::DoSwitchTemporaryColorMode(const int32_t userId, bool isDarkMode)
148 {
149     if (IsDarkModeCustomAuto(userId) || IsDarkModeSunsetSunrise(userId)) {
150         screenSwitchOperatorMgr_.ResetScreenOffOperateInfo();
151         int32_t settingStartTime = 0;
152         int32_t settingEndTime = 0;
153         auto res = GetSettingTime(userId, settingStartTime, settingEndTime);
154         if (res == false) {
155             LOGE("GetSettingTime faild userId: %{public}d", userId);
156             return;
157         }
158         if ((AlarmTimerManager::IsWithinTimeInterval(settingStartTime, settingEndTime) && isDarkMode == true) ||
159             (!AlarmTimerManager::IsWithinTimeInterval(settingStartTime, settingEndTime) && isDarkMode == false)) {
160             temporaryColorModeMgr_.SetColorModeNormal(userId);
161         } else {
162             temporaryColorModeMgr_.SetColorModeTemporary(userId);
163         }
164     }
165 }
166 
UpdateDarkModeSchedule(const DarkModeMode mode,const int32_t userId,const bool resetTempColorModeFlag,const bool bootLoadFlag)167 void DarkModeManager::UpdateDarkModeSchedule(
168     const DarkModeMode mode, const int32_t userId, const bool resetTempColorModeFlag, const bool bootLoadFlag)
169 {
170     screenSwitchOperatorMgr_.ResetScreenOffOperateInfo();
171     if (resetTempColorModeFlag == true) {
172         OnChangeDarkMode(mode, userId);
173         return;
174     }
175 
176     if (screenSwitchOperatorMgr_.IsScreenOff() || bootLoadFlag) {
177         if (temporaryColorModeMgr_.IsColorModeNormal(userId) ||
178             temporaryColorModeMgr_.CheckTemporaryStateEffective(userId) == false) {
179             OnChangeDarkMode(mode, userId);
180         }
181         return;
182     }
183 
184     if (temporaryColorModeMgr_.IsColorModeNormal(userId) ||
185         temporaryColorModeMgr_.CheckTemporaryStateEffective(userId) == false) {
186         screenSwitchOperatorMgr_.SetScreenOffOperateInfo(mode == DARK_MODE_ALWAYS_DARK, userId);
187         LOGI("SetScreenOffOperateInfo userId:%{public}d operate:%{public}d", userId, static_cast<int32_t>(mode));
188     }
189 }
190 
RestartTimer()191 ErrCode DarkModeManager::RestartTimer()
192 {
193     std::lock_guard lock(darkModeStatesMutex_);
194     DarkModeMode mode = darkModeStates_[settingDataObserversUserId_].settingMode;
195     int32_t startTime = -1;
196     int32_t endTime = -1;
197 
198     if (mode == DARK_MODE_SUNRISE_SUNSET) {
199         startTime = darkModeStates_[settingDataObserversUserId_].settingSunsetTime;
200         endTime = darkModeStates_[settingDataObserversUserId_].settingSunriseTime;
201     } else if (mode == DARK_MODE_CUSTOM_AUTO) {
202         startTime = darkModeStates_[settingDataObserversUserId_].settingStartTime;
203         endTime = darkModeStates_[settingDataObserversUserId_].settingEndTime;
204     } else {
205         LOGD("no need to restart timer.");
206         return ERR_OK;
207     }
208 
209     if (AlarmTimerManager::IsWithinTimeInterval(startTime, endTime)) {
210         UpdateDarkModeSchedule(DARK_MODE_ALWAYS_DARK, settingDataObserversUserId_, false, false);
211     } else {
212         UpdateDarkModeSchedule(DARK_MODE_ALWAYS_LIGHT, settingDataObserversUserId_, false, false);
213     }
214     return alarmTimerManager_.RestartAllTimer();
215 }
216 
IsDarkModeCustomAuto(const int32_t userId)217 bool DarkModeManager::IsDarkModeCustomAuto(const int32_t userId)
218 {
219     std::lock_guard lock(darkModeStatesMutex_);
220     return darkModeStates_[userId].settingMode == DARK_MODE_CUSTOM_AUTO;
221 }
222 
IsDarkModeSunsetSunrise(const int32_t userId)223 bool DarkModeManager::IsDarkModeSunsetSunrise(const int32_t userId)
224 {
225     std::lock_guard lock(darkModeStatesMutex_);
226     return darkModeStates_[userId].settingMode == DARK_MODE_SUNRISE_SUNSET;
227 }
228 
GetSettingTime(const int32_t userId,int32_t & settingStartTime,int32_t & settingEndTime)229 bool DarkModeManager::GetSettingTime(const int32_t userId, int32_t& settingStartTime, int32_t& settingEndTime)
230 {
231     std::lock_guard lock(darkModeStatesMutex_);
232     auto it = darkModeStates_.find(userId);
233     if (it != darkModeStates_.end()) {
234         if (it->second.settingMode == DARK_MODE_CUSTOM_AUTO) {
235             settingStartTime = it->second.settingStartTime;
236             settingEndTime = it->second.settingEndTime;
237         } else {
238             settingStartTime = it->second.settingSunsetTime;
239             settingEndTime = it->second.settingSunriseTime;
240         }
241         return true;
242     }
243     return false;
244 }
245 
IsColorModeNormal(const int32_t userId)246 bool DarkModeManager::IsColorModeNormal(const int32_t userId)
247 {
248     return temporaryColorModeMgr_.IsColorModeNormal(userId);
249 }
250 
Dump()251 void DarkModeManager::Dump()
252 {
253     {
254         std::lock_guard observersGuard(settingDataObserversMutex_);
255         LOGD("settingData observers size: %{public}zu, userId: %{public}d",
256             settingDataObservers_.size(), settingDataObserversUserId_);
257     }
258 
259     std::lock_guard stateGuard(darkModeStatesMutex_);
260     LOGD("darkModeStates size: %{public}zu", darkModeStates_.size());
261     for (const auto& state : darkModeStates_) {
262         LOGD("userId: %{public}d, mode: %{public}d, start: %{public}d, end: %{public}d",
263             state.first, state.second.settingMode, state.second.settingStartTime, state.second.settingEndTime);
264     }
265 
266     alarmTimerManager_.Dump();
267 }
268 
LoadSettingDataObserversCallback()269 void DarkModeManager::LoadSettingDataObserversCallback()
270 {
271     std::lock_guard lock(settingDataObserversMutex_);
272     settingDataObservers_.clear();
273     settingDataObservers_.emplace_back(SETTING_DARK_MODE_MODE, [&](const std::string& key, int32_t userId) {
274         SettingDataDarkModeModeUpdateFunc(key, userId);
275     });
276     settingDataObservers_.emplace_back(SETTING_DARK_MODE_START_TIME, [&](const std::string& key, int32_t userId) {
277         SettingDataDarkModeStartTimeUpdateFunc(key, userId);
278     });
279     settingDataObservers_.emplace_back(SETTING_DARK_MODE_END_TIME, [&](const std::string& key, int32_t userId) {
280         SettingDataDarkModeEndTimeUpdateFunc(key, userId);
281     });
282     settingDataObservers_.emplace_back(SETTING_DARK_MODE_SUN_SET, [&](const std::string& key, int32_t userId) {
283         SettingDataDarkModeSunsetTimeUpdateFunc(key, userId);
284     });
285     settingDataObservers_.emplace_back(SETTING_DARK_MODE_SUN_RISE, [&](const std::string& key, int32_t userId) {
286         SettingDataDarkModeSunriseTimeUpdateFunc(key, userId);
287     });
288 }
289 
RegisterSettingDataObserversLocked(const int32_t userId) const290 ErrCode DarkModeManager::RegisterSettingDataObserversLocked(const int32_t userId) const
291 {
292     SettingDataManager& manager = SettingDataManager::GetInstance();
293     size_t count = 0;
294     for (const auto& observer : settingDataObservers_) {
295         if (manager.RegisterObserver(observer.first, observer.second, userId) != ERR_OK) {
296             count++;
297         }
298     }
299     if (count != 0) {
300         LOGE("setting data observers are not all initialized");
301         return ERR_NO_INIT;
302     }
303     LOGD("setting data observers are all initialized");
304     return ERR_OK;
305 }
306 
UnregisterSettingDataObserversLocked(const int32_t userId) const307 void DarkModeManager::UnregisterSettingDataObserversLocked(const int32_t userId) const
308 {
309     SettingDataManager& manager = SettingDataManager::GetInstance();
310     for (const auto& observer : settingDataObservers_) {
311         manager.UnregisterObserver(observer.first, userId);
312     }
313 }
314 
SettingDataDarkModeModeUpdateFunc(const std::string & key,const int32_t userId)315 void DarkModeManager::SettingDataDarkModeModeUpdateFunc(const std::string& key, const int32_t userId)
316 {
317     SettingDataManager& manager = SettingDataManager::GetInstance();
318     int32_t value = DARK_MODE_INVALID;
319     ErrCode code = manager.GetInt32ValueStrictly(key, value, userId);
320     if (code != ERR_OK) {
321         LOGE("get dark mode value failed, key: %{public}s, userId: %{public}d, code: %{public}d, set to default",
322             key.c_str(), userId, code);
323         value = DARK_MODE_INVALID;
324     }
325     if (value < DARK_MODE_INVALID || value >= DARK_MODE_SIZE) {
326         LOGE("dark mode value is invalid, key: %{public}s, userId: %{public}d, value: %{public}d, set to default",
327             key.c_str(), userId, value);
328         value = DARK_MODE_INVALID;
329     }
330 
331     auto mode = static_cast<DarkModeMode>(value);
332     std::lock_guard lock(darkModeStatesMutex_);
333     LOGI("dark mode change, key: %{public}s, userId: %{public}d, from %{public}d to %{public}d",
334         key.c_str(), userId, darkModeStates_[userId].settingMode, value);
335     darkModeStates_[userId].settingMode = mode;
336     bool isDarkMode = false;
337     OnStateChangeLocked(userId, true, isDarkMode, true, false);
338 }
339 
SettingDataDarkModeStartTimeUpdateFunc(const std::string & key,const int32_t userId)340 void DarkModeManager::SettingDataDarkModeStartTimeUpdateFunc(const std::string& key, const int32_t userId)
341 {
342     SettingDataManager& manager = SettingDataManager::GetInstance();
343     int32_t value = -1;
344     manager.GetInt32ValueStrictly(key, value, userId);
345     std::lock_guard lock(darkModeStatesMutex_);
346     LOGI("dark mode start time change, key: %{public}s, userId: %{public}d, from %{public}d to %{public}d",
347         key.c_str(), userId, darkModeStates_[userId].settingStartTime, value);
348     darkModeStates_[userId].settingStartTime = value;
349     bool isDarkMode = false;
350     OnStateChangeLocked(userId, true, isDarkMode, true, false);
351 }
352 
SettingDataDarkModeEndTimeUpdateFunc(const std::string & key,const int32_t userId)353 void DarkModeManager::SettingDataDarkModeEndTimeUpdateFunc(const std::string& key, const int32_t userId)
354 {
355     SettingDataManager& manager = SettingDataManager::GetInstance();
356     int32_t value = -1;
357     manager.GetInt32ValueStrictly(key, value, userId);
358     std::lock_guard lock(darkModeStatesMutex_);
359     LOGI("dark mode end time change, key: %{public}s, userId: %{public}d, from %{public}d to %{public}d",
360         key.c_str(), userId, darkModeStates_[userId].settingEndTime, value);
361     darkModeStates_[userId].settingEndTime = value;
362     bool isDarkMode = false;
363     OnStateChangeLocked(userId, true, isDarkMode, true, false);
364 }
365 
SettingDataDarkModeSunsetTimeUpdateFunc(const std::string & key,const int32_t userId)366 void DarkModeManager::SettingDataDarkModeSunsetTimeUpdateFunc(const std::string& key, const int32_t userId)
367 {
368     SettingDataManager& manager = SettingDataManager::GetInstance();
369     int32_t value = SUNSET_TIME_DEFAULT;
370     manager.GetInt32ValueStrictly(key, value, userId);
371     std::lock_guard lock(darkModeStatesMutex_);
372     LOGI("dark mode sunset time change, key: %{public}s, userId: %{public}d, from %{public}d to %{public}d",
373         key.c_str(), userId, darkModeStates_[userId].settingSunsetTime, value);
374     if (value >= darkModeStates_[userId].settingSunriseTime) {
375         darkModeStates_[userId].settingSunsetTime = SUNSET_TIME_DEFAULT;
376         darkModeStates_[userId].settingSunriseTime = SUNRISE_TIME_DEFAULT;
377     } else {
378         darkModeStates_[userId].settingSunsetTime = value;
379     }
380     bool isDarkMode = false;
381     OnStateChangeLocked(userId, true, isDarkMode, false, false);
382 }
383 
SettingDataDarkModeSunriseTimeUpdateFunc(const std::string & key,const int32_t userId)384 void DarkModeManager::SettingDataDarkModeSunriseTimeUpdateFunc(const std::string& key, const int32_t userId)
385 {
386     SettingDataManager& manager = SettingDataManager::GetInstance();
387     int32_t value = SUNRISE_TIME_DEFAULT;
388     manager.GetInt32ValueStrictly(key, value, userId);
389     std::lock_guard lock(darkModeStatesMutex_);
390     LOGI("dark mode sunrise time change, key: %{public}s, userId: %{public}d, from %{public}d to %{public}d",
391         key.c_str(), userId, darkModeStates_[userId].settingSunriseTime, value);
392     if (value <= darkModeStates_[userId].settingSunsetTime) {
393         darkModeStates_[userId].settingSunsetTime = SUNSET_TIME_DEFAULT;
394         darkModeStates_[userId].settingSunriseTime = SUNRISE_TIME_DEFAULT;
395     } else {
396         darkModeStates_[userId].settingSunriseTime = value;
397     }
398     bool isDarkMode = false;
399     OnStateChangeLocked(userId, true, isDarkMode, false, false);
400 }
401 
OnStateChangeLocked(const int32_t userId,const bool needUpdateCallback,bool & isDarkMode,const bool resetTempColorModeFlag,const bool bootLoadFlag)402 ErrCode DarkModeManager::OnStateChangeLocked(const int32_t userId, const bool needUpdateCallback, bool& isDarkMode,
403     const bool resetTempColorModeFlag, const bool bootLoadFlag)
404 {
405     ErrCode code = ERR_OK;
406     DarkModeState& state = darkModeStates_[userId];
407     switch (state.settingMode) {
408         case DARK_MODE_ALWAYS_LIGHT:
409         case DARK_MODE_ALWAYS_DARK:
410             code = OnStateChangeToAllDayMode(
411                 userId, state.settingMode, needUpdateCallback, isDarkMode, resetTempColorModeFlag, bootLoadFlag);
412             break;
413         case DARK_MODE_CUSTOM_AUTO:
414         case DARK_MODE_SUNRISE_SUNSET:
415             code = OnStateChangeToCustomAutoMode(userId, state, needUpdateCallback, isDarkMode, resetTempColorModeFlag,
416                 bootLoadFlag);
417             break;
418         default:
419             // do nothing
420             code = ERR_INVALID_OPERATION;
421             break;
422     }
423     return code;
424 }
425 
OnStateChangeToAllDayMode(const int32_t userId,const DarkModeMode darkMode,const bool needUpdateCallback,bool & isDarkMode,const bool resetTempColorModeFlag,const bool bootLoadFlag)426 ErrCode DarkModeManager::OnStateChangeToAllDayMode(const int32_t userId, const DarkModeMode darkMode,
427     const bool needUpdateCallback, bool& isDarkMode, const bool resetTempColorModeFlag, const bool bootLoadFlag)
428 {
429     alarmTimerManager_.ClearTimerByUserId(userId);
430     isDarkMode = darkMode == DARK_MODE_ALWAYS_DARK;
431     if (needUpdateCallback) {
432         UpdateDarkModeSchedule(darkMode, userId, resetTempColorModeFlag, bootLoadFlag);
433     }
434     return ERR_OK;
435 }
436 
OnStateChangeToCustomAutoMode(const int32_t userId,const DarkModeState & state,const bool needUpdateCallback,bool & isDarkMode,const bool resetTempColorModeFlag,const bool bootLoadFlag)437 ErrCode DarkModeManager::OnStateChangeToCustomAutoMode(const int32_t userId, const DarkModeState& state,
438     const bool needUpdateCallback, bool& isDarkMode, const bool resetTempColorModeFlag, const bool bootLoadFlag)
439 {
440     int32_t startTime = -1;
441     int32_t endTime = -1;
442     if (state.settingMode == DARK_MODE_SUNRISE_SUNSET) {
443         startTime = state.settingSunsetTime;
444         endTime = state.settingSunriseTime;
445     } else {
446         startTime = state.settingStartTime;
447         endTime = state.settingEndTime;
448     }
449 
450     ErrCode code = CreateOrUpdateTimers(startTime, endTime, userId);
451     if (code != ERR_OK) {
452         alarmTimerManager_.ClearTimerByUserId(userId);
453         return code;
454     }
455     DarkModeMode mode = DARK_MODE_INVALID;
456     if (AlarmTimerManager::IsWithinTimeInterval(startTime, endTime)) {
457         isDarkMode = true;
458         mode = DARK_MODE_ALWAYS_DARK;
459     } else {
460         isDarkMode = false;
461         mode = DARK_MODE_ALWAYS_LIGHT;
462     }
463 
464     if (needUpdateCallback) {
465         UpdateDarkModeSchedule(mode, userId, resetTempColorModeFlag, bootLoadFlag);
466     }
467     return ERR_OK;
468 }
469 
OnChangeDarkMode(const DarkModeMode mode,const int32_t userId)470 void DarkModeManager::OnChangeDarkMode(const DarkModeMode mode, const int32_t userId)
471 {
472     if (!updateCallback_) {
473         LOGE("no update callback, mode: %{public}d, userId: %{public}d", mode, userId);
474         return;
475     }
476     updateCallback_(mode == DARK_MODE_ALWAYS_DARK, userId);
477     if (temporaryColorModeMgr_.IsColorModeTemporary(userId)) {
478         temporaryColorModeMgr_.SetColorModeNormal(userId);
479     }
480 }
481 
CreateOrUpdateTimers(int32_t startTime,int32_t endTime,int32_t userId)482 ErrCode DarkModeManager::CreateOrUpdateTimers(int32_t startTime, int32_t endTime, int32_t userId)
483 {
484     auto callbackSetDark = [startTime, endTime, userId]() {
485         LOGI("timer callback, startTime: %{public}d, endTime: %{public}d, userId: %{public}d",
486             startTime, endTime, userId);
487         ErrCode code = GetInstance().CheckTimerCallbackParams(startTime, endTime, userId);
488         if (code != ERR_OK) {
489             LOGE("timer callback, params check failed: %{public}d", code);
490             return;
491         }
492         GetInstance().UpdateDarkModeSchedule(DARK_MODE_ALWAYS_DARK, userId, false, false);
493     };
494 
495     auto callbackSetLight = [startTime, endTime, userId]() {
496         LOGI("timer callback, startTime: %{public}d, endTime: %{public}d, userId: %{public}d",
497             startTime, endTime, userId);
498         ErrCode code = GetInstance().CheckTimerCallbackParams(startTime, endTime, userId);
499         if (code != ERR_OK) {
500             LOGE("timer callback, params check failed: %{public}d", code);
501             return;
502         }
503         GetInstance().UpdateDarkModeSchedule(DARK_MODE_ALWAYS_LIGHT, userId, false, false);
504     };
505 
506     return alarmTimerManager_.SetScheduleTime(startTime, endTime, userId, callbackSetDark, callbackSetLight);
507 }
508 
CheckTimerCallbackParams(const int32_t startTime,const int32_t endTime,const int32_t userId)509 ErrCode DarkModeManager::CheckTimerCallbackParams(const int32_t startTime, const int32_t endTime, const int32_t userId)
510 {
511     std::lock_guard lock(darkModeStatesMutex_);
512     DarkModeState& state = darkModeStates_[userId];
513     if (state.settingMode == DARK_MODE_CUSTOM_AUTO) {
514         if (state.settingStartTime != startTime) {
515             LOGE("timer callback, param wrong, startTime: %{public}d, setting: %{public}d",
516                 startTime, state.settingStartTime);
517             return ERR_INVALID_OPERATION;
518         }
519         if (state.settingEndTime != endTime) {
520             LOGE("timer callback, param wrong, endTime: %{public}d, setting: %{public}d",
521                 endTime, state.settingEndTime);
522             return ERR_INVALID_OPERATION;
523         }
524     } else if (state.settingMode == DARK_MODE_SUNRISE_SUNSET) {
525         if (state.settingSunsetTime != startTime) {
526             LOGE("timer callback, param wrong, sunsetTime: %{public}d, setting: %{public}d",
527                 startTime, state.settingSunsetTime);
528             return ERR_INVALID_OPERATION;
529         }
530         if (state.settingSunriseTime != endTime) {
531             LOGE("timer callback, param wrong, sunriseTime: %{public}d, setting: %{public}d",
532                 endTime, state.settingSunriseTime);
533             return ERR_INVALID_OPERATION;
534         }
535     } else {
536         LOGE("timer callback, param wrong, setting mode: %{public}d", state.settingMode);
537         return ERR_INVALID_OPERATION;
538     }
539     return ERR_OK;
540 }
541 } // namespace OHOS::ArkUi::UiAppearance
542