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