支持临时深浅色

Signed-off-by: wlh2624 <1968860844@qq.com>
Change-Id: Ibfae9667c9740e358eb91f8dc9e8f7f075962b61
This commit is contained in:
wlh2624
2025-01-05 19:51:28 +08:00
parent 631b66bf12
commit a904b2d60c
14 changed files with 717 additions and 69 deletions
+3
View File
@@ -18,3 +18,6 @@ persist.ace.darkmode. = uiserver:servicectrl:0700
persist.sys.font_scale_for_user. = uiserver:servicectrl:0700
persist.sys.font_wght_scale_for_user. = uiserver:servicectrl:0700
persist.uiAppearance.first_initialization = uiserver:servicectrl:0700
persist.uiAppearance.dark_mode_temp_state_flag. = uiserver:servicectrl:0700
persist.uiAppearance.dark_mode_temp_state_start_time. = uiserver:servicectrl:0700
persist.uiAppearance.dark_mode_temp_state_end_time. = uiserver:servicectrl:0700
+3
View File
@@ -30,10 +30,13 @@ ohos_shared_library("ui_appearance_service") {
sources = [
"src/dark_mode_manager.cpp",
"src/dark_mode_temp_state_manager.cpp",
"src/screen_switch_operator_manager.cpp",
"src/ui_appearance_ability.cpp",
"src/ui_appearance_ability_stub.cpp",
"utils/src/alarm_timer.cpp",
"utils/src/alarm_timer_manager.cpp",
"utils/src/parameter_wrap.cpp",
"utils/src/setting_data_manager.cpp",
"utils/src/setting_data_observer.cpp",
]
+27 -6
View File
@@ -22,13 +22,15 @@
#include "errors.h"
#include "nocopyable.h"
#include "alarm_timer_manager.h"
#include "dark_mode_temp_state_manager.h"
#include "screen_switch_operator_manager.h"
namespace OHOS::ArkUi::UiAppearance {
class DarkModeManager final : public NoCopyable {
public:
static DarkModeManager &GetInstance();
ErrCode Initialize(const std::function<void(bool, int32_t)> &updateCallback);
ErrCode Initialize(const std::function<void(bool, int32_t)>& updateCallback);
ErrCode LoadUserSettingData(int32_t userId, bool needUpdateCallback, bool &isDarkMode);
@@ -36,10 +38,20 @@ public:
ErrCode OnSwitchUser(int32_t userId);
void ScreenOnCallback();
void ScreenOffCallback();
ErrCode RestartTimer();
void Dump();
bool GetSettingTime(const int32_t userId, int32_t& settingStartTime, int32_t& settingEndTime);
bool IsColorModeNormal(const int32_t userId);
void DoSwitchTemporaryColorMode(const int32_t userId, bool isDarkMode);
private:
enum DarkModeMode {
DARK_MODE_INVALID = -1,
@@ -67,19 +79,25 @@ private:
void SettingDataDarkModeEndTimeUpdateFunc(const std::string& key, int32_t userId);
ErrCode OnStateChangeLocked(int32_t userId, bool needUpdateCallback, bool &isDarkMode);
ErrCode OnStateChangeLocked(
int32_t userId, bool needUpdateCallback, bool& isDarkMode, const bool resetTempColorModeFlag);
ErrCode OnStateChangeToAllDayMode(int32_t userId, DarkModeMode darkMode, bool needUpdateCallback, bool &isDarkMode);
ErrCode OnStateChangeToAllDayMode(int32_t userId, DarkModeMode darkMode, bool needUpdateCallback, bool& isDarkMode,
const bool resetTempColorModeFlag);
ErrCode OnStateChangeToCustomAutoMode(
int32_t userId, const DarkModeState& state, bool needUpdateCallback, bool &isDarkMode);
ErrCode OnStateChangeToCustomAutoMode(int32_t userId, const DarkModeState& state, bool needUpdateCallback,
bool& isDarkMode, const bool resetTempColorModeFlag);
void OnChangeDarkMode(DarkModeMode mode, int32_t userId) const;
void OnChangeDarkMode(DarkModeMode mode, int32_t userId);
ErrCode CreateOrUpdateTimers(int32_t startTime, int32_t endTime, int32_t userId);
ErrCode CheckTimerCallbackParams(int32_t startTime, int32_t endTime, int32_t userId);
void UpdateDarkModeSchedule(const DarkModeMode isDarkMode, const int32_t userId, const bool resetTempColorModeFlag);
bool IsDarkModeCustomAuto(const int32_t userId);
std::mutex settingDataObserversMutex_;
std::vector<std::pair<std::string, std::function<void(const std::string&, int32_t)>>> settingDataObservers_;
int32_t settingDataObserversUserId_ = -1;
@@ -89,6 +107,9 @@ private:
std::map<int32_t, DarkModeState> darkModeStates_;
std::function<void(bool, int32_t)> updateCallback_;
TemporaryColorModeManager temporaryColorModeMgr_;
ScreenSwitchOperatorManager screenSwitchOperatorMgr_;
};
} // namespace OHOS::ArkUi::UiAppearance
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef UI_APPEARANCE_DARK_MODE_TEMP_STATE_MANAGER_H
#define UI_APPEARANCE_DARK_MODE_TEMP_STATE_MANAGER_H
#include <functional>
#include <vector>
#include "errors.h"
#include "map"
#include "mutex"
namespace OHOS::ArkUi::UiAppearance {
class TemporaryColorModeManager {
public:
void InitData(const int32_t userId);
bool IsColorModeTemporary(const int32_t userId);
bool IsColorModeNormal(const int32_t userId);
bool SetColorModeTemporary(const int32_t userId);
bool SetColorModeNormal(const int32_t userId);
bool CheckTemporaryStateEffective(const int32_t userId);
private:
std::string TemporaryColorModeAssignUser(const int32_t userId);
std::string TemporaryStateStartTimeAssignUser(const int32_t userId);
std::string TemporaryStateEndTimeAssignUser(const int32_t userId);
static bool IsWithInPreInterval(const int32_t startTime, const int32_t endTime);
static void GetTempColorModeTimeInfo(const int32_t settingStartTime, const int32_t settingEndTime,
int64_t& tempStateStartTime, int64_t& tempStateEndTime);
void SaveTempColorModeInfo(const int32_t userId);
enum class TempColorModeType {
ColorModeNormal = 0,
ColorModeTemp,
};
struct TempColorModeInfo {
TempColorModeType tempColorMode = TempColorModeType::ColorModeNormal;
int64_t keepTemporaryStateStartTime = 0;
int64_t keepTemporaryStateEndTime = 0;
};
std::mutex multiUserTempColorModeMapMutex_;
std::map<int32_t, TempColorModeInfo> multiUserTempColorModeMap_;
};
} // namespace OHOS::ArkUi::UiAppearance
#endif // UI_APPEARANCE_DARK_MODE_TEMP_STATE_MANAGER_H
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef UI_APPEARANCE_SCREEN_SWITCH_OPERATOR_MANAGER_H
#define UI_APPEARANCE_SCREEN_SWITCH_OPERATOR_MANAGER_H
#include <functional>
#include <vector>
#include <mutex>
namespace OHOS::ArkUi::UiAppearance {
class ScreenSwitchOperatorManager {
public:
bool IsScreenOn();
bool IsScreenOff();
void SetScreenOn();
void SetScreenOff();
void ResetScreenOffOperateInfo();
void SetScreenOffOperateInfo(const bool switchToDark, const int32_t userId);
void GetScreenOffOperateInfo(bool &switchToDark, int32_t &userId);
bool HaveScreenOffOperate();
private:
enum class ScreenSwitchType {
SCREEN_OFF = 0,
SCREEN_ON,
};
enum class ScreenOffOperateType {
NONE = 0,
SWITCH_TO_LIGHT,
SWITCH_TO_DARK,
};
struct ScreenOffOperateInfoType {
ScreenOffOperateType screenOffOperator = ScreenOffOperateType::NONE;
int32_t userId;
};
std::mutex screenSwitchMutex_;
ScreenSwitchType screenSwitch_;
std::mutex screenOffOperateInfoMutex_;
ScreenOffOperateInfoType screenOffOperateInfo_;
};
} // namespace OHOS::ArkUi::UiAppearance
#endif // UI_APPEARANCE_SCREEN_SWITCH_OPERATOR_MANAGER_H
-4
View File
@@ -81,10 +81,6 @@ private:
void UserSwitchFunc(const int32_t userId);
void DoInitProcess();
bool GetParameterWrap(const std::string& paramName, std::string& value, const std::string& defaultValue);
bool GetParameterWrap(const std::string& paramName, std::string& value);
bool SetParameterWrap(const std::string& paramName, const std::string& value);
void UpdateCurrentUserConfiguration(const int32_t userId, const bool isForceUpdate);
int32_t OnSetDarkMode(const int32_t userId, DarkMode mode);
UiAppearanceAbility::DarkMode InitGetDarkMode(const int32_t userId);
+116 -18
View File
@@ -23,6 +23,7 @@ namespace {
const std::string SETTING_DARK_MODE_MODE = "settings.uiappearance.darkmode_mode";
const std::string SETTING_DARK_MODE_START_TIME = "settings.uiappearance.darkmode_starttime";
const std::string SETTING_DARK_MODE_END_TIME = "settings.uiappearance.darkmode_endtime";
const static int32_t USER100 = 100;
}
DarkModeManager &DarkModeManager::GetInstance()
@@ -59,7 +60,13 @@ ErrCode DarkModeManager::LoadUserSettingData(const int32_t userId, const bool ne
state.settingEndTime = endTime;
LOGI("load user setting data, userId: %{public}d, mode: %{public}d, start: %{public}d, end : %{public}d",
userId, darkMode, startTime, endTime);
return OnStateChangeLocked(userId, needUpdateCallback, isDarkMode);
temporaryColorModeMgr_.InitData(userId);
if (temporaryColorModeMgr_.IsColorModeTemporary(userId) &&
temporaryColorModeMgr_.CheckTemporaryStateEffective(userId) == false) {
temporaryColorModeMgr_.SetColorModeNormal(userId);
}
screenSwitchOperatorMgr_.ResetScreenOffOperateInfo();
return OnStateChangeLocked(userId, needUpdateCallback, isDarkMode, false);
}
void DarkModeManager::NotifyDarkModeUpdate(const int32_t userId, const bool isDarkMode)
@@ -80,6 +87,25 @@ void DarkModeManager::NotifyDarkModeUpdate(const int32_t userId, const bool isDa
}
}
void DarkModeManager::ScreenOnCallback()
{
screenSwitchOperatorMgr_.SetScreenOn();
}
void DarkModeManager::ScreenOffCallback()
{
screenSwitchOperatorMgr_.SetScreenOff();
if (screenSwitchOperatorMgr_.HaveScreenOffOperate()) {
bool switchToDark = false;
int32_t userId = USER100;
screenSwitchOperatorMgr_.GetScreenOffOperateInfo(switchToDark, userId);
OnChangeDarkMode(
switchToDark == true ? DarkModeMode::DARK_MODE_ALWAYS_DARK : DarkModeMode::DARK_MODE_ALWAYS_LIGHT,
userId);
screenSwitchOperatorMgr_.ResetScreenOffOperateInfo();
}
}
ErrCode DarkModeManager::OnSwitchUser(const int32_t userId)
{
SettingDataManager& manager = SettingDataManager::GetInstance();
@@ -109,6 +135,50 @@ ErrCode DarkModeManager::OnSwitchUser(const int32_t userId)
return code;
}
void DarkModeManager::DoSwitchTemporaryColorMode(const int32_t userId, bool isDarkMode)
{
if (IsDarkModeCustomAuto(userId)) {
screenSwitchOperatorMgr_.ResetScreenOffOperateInfo();
int32_t settingStartTime = 0;
int32_t settingEndTime = 0;
auto res = GetSettingTime(userId, settingStartTime, settingEndTime);
if (res == false) {
LOGE("GetSettingTime faild userId: %{public}d", userId);
return;
}
if ((AlarmTimerManager::IsWithinTimeInterval(settingStartTime, settingEndTime) && isDarkMode == true) ||
(!AlarmTimerManager::IsWithinTimeInterval(settingStartTime, settingEndTime) && isDarkMode == false)) {
temporaryColorModeMgr_.SetColorModeNormal(userId);
} else {
temporaryColorModeMgr_.SetColorModeTemporary(userId);
}
}
}
void DarkModeManager::UpdateDarkModeSchedule(
const DarkModeMode mode, const int32_t userId, const bool resetTempColorModeFlag)
{
screenSwitchOperatorMgr_.ResetScreenOffOperateInfo();
if (resetTempColorModeFlag == true) {
OnChangeDarkMode(mode, userId);
return;
}
if (screenSwitchOperatorMgr_.IsScreenOff()) {
if (temporaryColorModeMgr_.IsColorModeNormal(userId) ||
temporaryColorModeMgr_.CheckTemporaryStateEffective(userId) == false) {
OnChangeDarkMode(mode, userId);
}
return;
}
if (temporaryColorModeMgr_.IsColorModeNormal(userId) ||
temporaryColorModeMgr_.CheckTemporaryStateEffective(userId) == false) {
screenSwitchOperatorMgr_.SetScreenOffOperateInfo(mode == DARK_MODE_ALWAYS_DARK, userId);
LOGI("SetScreenOffOperateInfo userId:%{public}d operate:%{public}d", userId, static_cast<int32_t>(mode));
}
}
ErrCode DarkModeManager::RestartTimer()
{
std::lock_guard lock(darkModeStatesMutex_);
@@ -121,13 +191,36 @@ ErrCode DarkModeManager::RestartTimer()
int32_t startTime = darkModeStates_[settingDataObserversUserId_].settingStartTime;
int32_t endTime = darkModeStates_[settingDataObserversUserId_].settingEndTime;
if (AlarmTimerManager::IsWithinTimeInterval(startTime, endTime)) {
OnChangeDarkMode(DARK_MODE_ALWAYS_DARK, settingDataObserversUserId_);
UpdateDarkModeSchedule(DARK_MODE_ALWAYS_DARK, settingDataObserversUserId_, false);
} else {
OnChangeDarkMode(DARK_MODE_ALWAYS_LIGHT, settingDataObserversUserId_);
UpdateDarkModeSchedule(DARK_MODE_ALWAYS_LIGHT, settingDataObserversUserId_, false);
}
return alarmTimerManager_.RestartAllTimer();
}
bool DarkModeManager::IsDarkModeCustomAuto(const int32_t userId)
{
std::lock_guard lock(darkModeStatesMutex_);
return darkModeStates_[userId].settingMode == DARK_MODE_CUSTOM_AUTO;
}
bool DarkModeManager::GetSettingTime(const int32_t userId, int32_t& settingStartTime, int32_t& settingEndTime)
{
std::lock_guard lock(darkModeStatesMutex_);
auto it = darkModeStates_.find(userId);
if (it != darkModeStates_.end()) {
settingStartTime = it->second.settingStartTime;
settingEndTime = it->second.settingEndTime;
return true;
}
return false;
}
bool DarkModeManager::IsColorModeNormal(const int32_t userId)
{
return temporaryColorModeMgr_.IsColorModeNormal(userId);
}
void DarkModeManager::Dump()
{
{
@@ -208,7 +301,7 @@ void DarkModeManager::SettingDataDarkModeModeUpdateFunc(const std::string& key,
key.c_str(), userId, darkModeStates_[userId].settingMode, value);
darkModeStates_[userId].settingMode = mode;
bool isDarkMode = false;
OnStateChangeLocked(userId, true, isDarkMode);
OnStateChangeLocked(userId, true, isDarkMode, true);
}
void DarkModeManager::SettingDataDarkModeStartTimeUpdateFunc(const std::string& key, const int32_t userId)
@@ -221,7 +314,7 @@ void DarkModeManager::SettingDataDarkModeStartTimeUpdateFunc(const std::string&
key.c_str(), userId, darkModeStates_[userId].settingStartTime, value);
darkModeStates_[userId].settingStartTime = value;
bool isDarkMode = false;
OnStateChangeLocked(userId, true, isDarkMode);
OnStateChangeLocked(userId, true, isDarkMode, true);
}
void DarkModeManager::SettingDataDarkModeEndTimeUpdateFunc(const std::string& key, const int32_t userId)
@@ -234,20 +327,22 @@ void DarkModeManager::SettingDataDarkModeEndTimeUpdateFunc(const std::string& ke
key.c_str(), userId, darkModeStates_[userId].settingEndTime, value);
darkModeStates_[userId].settingEndTime = value;
bool isDarkMode = false;
OnStateChangeLocked(userId, true, isDarkMode);
OnStateChangeLocked(userId, true, isDarkMode, true);
}
ErrCode DarkModeManager::OnStateChangeLocked(const int32_t userId, const bool needUpdateCallback, bool& isDarkMode)
ErrCode DarkModeManager::OnStateChangeLocked(
const int32_t userId, const bool needUpdateCallback, bool& isDarkMode, const bool resetTempColorModeFlag)
{
ErrCode code = ERR_OK;
DarkModeState& state = darkModeStates_[userId];
switch (state.settingMode) {
case DARK_MODE_ALWAYS_LIGHT:
case DARK_MODE_ALWAYS_DARK:
code = OnStateChangeToAllDayMode(userId, state.settingMode, needUpdateCallback, isDarkMode);
code = OnStateChangeToAllDayMode(
userId, state.settingMode, needUpdateCallback, isDarkMode, resetTempColorModeFlag);
break;
case DARK_MODE_CUSTOM_AUTO:
code = OnStateChangeToCustomAutoMode(userId, state, needUpdateCallback, isDarkMode);
code = OnStateChangeToCustomAutoMode(userId, state, needUpdateCallback, isDarkMode, resetTempColorModeFlag);
break;
default:
// do nothing
@@ -257,19 +352,19 @@ ErrCode DarkModeManager::OnStateChangeLocked(const int32_t userId, const bool ne
return code;
}
ErrCode DarkModeManager::OnStateChangeToAllDayMode(
const int32_t userId, const DarkModeMode darkMode, const bool needUpdateCallback, bool &isDarkMode)
ErrCode DarkModeManager::OnStateChangeToAllDayMode(const int32_t userId, const DarkModeMode darkMode,
const bool needUpdateCallback, bool& isDarkMode, const bool resetTempColorModeFlag)
{
alarmTimerManager_.ClearTimerByUserId(userId);
isDarkMode = darkMode == DARK_MODE_ALWAYS_DARK;
if (needUpdateCallback) {
OnChangeDarkMode(darkMode, userId);
UpdateDarkModeSchedule(darkMode, userId, resetTempColorModeFlag);
}
return ERR_OK;
}
ErrCode DarkModeManager::OnStateChangeToCustomAutoMode(
const int32_t userId, const DarkModeState& state, const bool needUpdateCallback, bool &isDarkMode)
ErrCode DarkModeManager::OnStateChangeToCustomAutoMode(const int32_t userId, const DarkModeState& state,
const bool needUpdateCallback, bool& isDarkMode, const bool resetTempColorModeFlag)
{
ErrCode code = CreateOrUpdateTimers(state.settingStartTime, state.settingEndTime, userId);
if (code != ERR_OK) {
@@ -286,18 +381,21 @@ ErrCode DarkModeManager::OnStateChangeToCustomAutoMode(
}
if (needUpdateCallback) {
OnChangeDarkMode(mode, userId);
UpdateDarkModeSchedule(mode, userId, resetTempColorModeFlag);
}
return ERR_OK;
}
void DarkModeManager::OnChangeDarkMode(const DarkModeMode mode, const int32_t userId) const
void DarkModeManager::OnChangeDarkMode(const DarkModeMode mode, const int32_t userId)
{
if (!updateCallback_) {
LOGE("no update callback, mode: %{public}d, userId: %{public}d", mode, userId);
return;
}
updateCallback_(mode == DARK_MODE_ALWAYS_DARK, userId);
if (temporaryColorModeMgr_.IsColorModeTemporary(userId)) {
temporaryColorModeMgr_.SetColorModeNormal(userId);
}
}
ErrCode DarkModeManager::CreateOrUpdateTimers(int32_t startTime, int32_t endTime, int32_t userId)
@@ -310,7 +408,7 @@ ErrCode DarkModeManager::CreateOrUpdateTimers(int32_t startTime, int32_t endTime
LOGE("timer callback, params check failed: %{public}d", code);
return;
}
GetInstance().OnChangeDarkMode(DARK_MODE_ALWAYS_DARK, userId);
GetInstance().UpdateDarkModeSchedule(DARK_MODE_ALWAYS_DARK, userId, false);
};
auto callbackSetLight = [startTime, endTime, userId]() {
@@ -321,7 +419,7 @@ ErrCode DarkModeManager::CreateOrUpdateTimers(int32_t startTime, int32_t endTime
LOGE("timer callback, params check failed: %{public}d", code);
return;
}
GetInstance().OnChangeDarkMode(DARK_MODE_ALWAYS_LIGHT, userId);
GetInstance().UpdateDarkModeSchedule(DARK_MODE_ALWAYS_LIGHT, userId, false);
};
return alarmTimerManager_.SetScheduleTime(startTime, endTime, userId, callbackSetDark, callbackSetLight);
@@ -0,0 +1,276 @@
/*
* Copyright (c) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dark_mode_temp_state_manager.h"
#include <ctime>
#include <sys/time.h>
#include <cinttypes>
#include "dark_mode_manager.h"
#include "parameter_wrap.h"
#include "ui_appearance_log.h"
namespace OHOS::ArkUi::UiAppearance {
namespace {
static const std::string TEMPORARY_COLOR_MODE_PARAM_STRING = "persist.uiAppearance.dark_mode_temp_state_flag.";
static const std::string TEMPORARY_STATE_START_TIME_PARAM_STRING =
"persist.uiAppearance.dark_mode_temp_state_start_time.";
static const std::string TEMPORARY_STATE_END_TIME_PARAM_STRING = "persist.uiAppearance.dark_mode_temp_state_end_time.";
static const std::string TEMPORARY_COLOR_MODE_TEMPORARY_STRING = "1";
static const std::string TEMPORARY_COLOR_MODE_NORMAL_STRING = "0";
constexpr int32_t DAY_TO_MINUTE = 24 * 60;
constexpr int32_t HOUR_TO_MINUTE = 60;
constexpr int32_t MINUTE_TO_SECOND = 60;
} // namespace
void TemporaryColorModeManager::InitData(const int32_t userId)
{
TempColorModeInfo info;
std::string temporaryColorModeValue = TEMPORARY_COLOR_MODE_NORMAL_STRING;
GetParameterWrap(TemporaryColorModeAssignUser(userId), temporaryColorModeValue);
info.tempColorMode = temporaryColorModeValue == TEMPORARY_COLOR_MODE_NORMAL_STRING
? TempColorModeType::ColorModeNormal
: TempColorModeType::ColorModeTemp;
if (info.tempColorMode == TempColorModeType::ColorModeTemp) {
std::string startTime = "0";
GetParameterWrap(TemporaryStateStartTimeAssignUser(userId), startTime);
info.keepTemporaryStateStartTime = atoll(startTime.c_str());
std::string endTime = "0";
GetParameterWrap(TemporaryStateEndTimeAssignUser(userId), endTime);
info.keepTemporaryStateEndTime = atoll(endTime.c_str());
}
{
std::lock_guard guard(multiUserTempColorModeMapMutex_);
multiUserTempColorModeMap_[userId] = info;
}
LOGI("init temp colormode info userId:%{public}d, tempColorMode:%{public}d, keepStartTime:%{public}" PRId64
", keepEndTime:%{public}" PRId64,
userId, static_cast<int32_t>(info.tempColorMode), info.keepTemporaryStateStartTime,
info.keepTemporaryStateEndTime);
}
bool TemporaryColorModeManager::IsColorModeTemporary(const int32_t userId)
{
std::lock_guard guard(multiUserTempColorModeMapMutex_);
auto it = multiUserTempColorModeMap_.find(userId);
if (it != multiUserTempColorModeMap_.end()) {
return it->second.tempColorMode == TempColorModeType::ColorModeTemp;
}
return false;
}
bool TemporaryColorModeManager::IsColorModeNormal(const int32_t userId)
{
std::lock_guard guard(multiUserTempColorModeMapMutex_);
auto it = multiUserTempColorModeMap_.find(userId);
if (it != multiUserTempColorModeMap_.end()) {
return it->second.tempColorMode == TempColorModeType::ColorModeNormal;
}
return true;
}
bool TemporaryColorModeManager::SetColorModeTemporary(const int32_t userId)
{
{
std::lock_guard guard(multiUserTempColorModeMapMutex_);
multiUserTempColorModeMap_[userId].tempColorMode = TempColorModeType::ColorModeTemp;
int32_t settingStartTime = 0;
int32_t settingEndTime = 0;
auto res = DarkModeManager::GetInstance().GetSettingTime(userId, settingStartTime, settingEndTime);
if (res == false) {
LOGE("GetSettingTime faild userId: %{public}d", userId);
return false;
}
GetTempColorModeTimeInfo(settingStartTime, settingEndTime,
multiUserTempColorModeMap_[userId].keepTemporaryStateStartTime,
multiUserTempColorModeMap_[userId].keepTemporaryStateEndTime);
}
SaveTempColorModeInfo(userId);
return true;
}
bool TemporaryColorModeManager::SetColorModeNormal(const int32_t userId)
{
{
std::lock_guard guard(multiUserTempColorModeMapMutex_);
multiUserTempColorModeMap_[userId].tempColorMode = TempColorModeType::ColorModeNormal;
multiUserTempColorModeMap_[userId].keepTemporaryStateStartTime = 0;
multiUserTempColorModeMap_[userId].keepTemporaryStateEndTime = 0;
}
SaveTempColorModeInfo(userId);
return true;
}
bool TemporaryColorModeManager::CheckTemporaryStateEffective(const int32_t userId)
{
auto checkTempStateNoTimeout = [](const int64_t startTime, const int64_t endTime) {
std::time_t timestampNow = std::time(nullptr);
if (timestampNow == static_cast<std::time_t>(-1)) {
LOGE("fail to get timestamp");
return false;
}
if (startTime < timestampNow && timestampNow < endTime) {
return true;
}
return false;
};
std::lock_guard guard(multiUserTempColorModeMapMutex_);
auto it = multiUserTempColorModeMap_.find(userId);
if (it != multiUserTempColorModeMap_.end()) {
if (it->second.tempColorMode == TempColorModeType::ColorModeTemp &&
checkTempStateNoTimeout(it->second.keepTemporaryStateStartTime, it->second.keepTemporaryStateEndTime)) {
return true;
}
}
return false;
}
std::string TemporaryColorModeManager::TemporaryColorModeAssignUser(const int32_t userId)
{
return TEMPORARY_COLOR_MODE_PARAM_STRING + std::to_string(userId);
}
std::string TemporaryColorModeManager::TemporaryStateStartTimeAssignUser(const int32_t userId)
{
return TEMPORARY_STATE_START_TIME_PARAM_STRING + std::to_string(userId);
}
std::string TemporaryColorModeManager::TemporaryStateEndTimeAssignUser(const int32_t userId)
{
return TEMPORARY_STATE_END_TIME_PARAM_STRING + std::to_string(userId);
}
void TemporaryColorModeManager::GetTempColorModeTimeInfo(const int32_t settingStartTime,
const int32_t settingEndTime, int64_t& tempStateStartTime, int64_t& tempStateEndTime)
{
auto calcEndTimestamp = [](const int32_t secondOffset, int64_t& endTimeStamp) {
std::time_t timestamp = std::time(nullptr);
if (timestamp == static_cast<std::time_t>(-1)) {
LOGE("fail to get timestamp");
return false;
}
std::tm* nowTime = std::localtime(&timestamp);
if (nowTime != nullptr) {
nowTime->tm_hour = 0;
nowTime->tm_min = 0;
nowTime->tm_sec = 0;
}
std::time_t midnightTime = std::mktime(nowTime);
endTimeStamp = midnightTime + secondOffset - 1;
return true;
};
tempStateStartTime = static_cast<int64_t>(std::time(nullptr));
if (settingEndTime > DAY_TO_MINUTE) {
if (AlarmTimerManager::IsWithinTimeInterval(settingStartTime, settingEndTime) == false) {
/*********************************************************************
for example settingStartTime=20, settingEndTime=8
↓(setting)
xxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxx
0 8 20 24(0) 8 20 24
|-----------------------------------|
************************************************************************/
calcEndTimestamp((settingEndTime * MINUTE_TO_SECOND), tempStateEndTime);
} else if (TemporaryColorModeManager::IsWithInPreInterval(settingStartTime, settingEndTime)) {
/*********************************************************************
for example settingStartTime=20, settingEndTime=8
↓(setting)
xxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxx
0 8 20 24(0) 8 20 24
|-----------------|
************************************************************************/
calcEndTimestamp((settingStartTime * MINUTE_TO_SECOND), tempStateEndTime);
} else {
/*********************************************************************
for example settingStartTime=20, settingEndTime=8
↓(setting)
xxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxx
0 8 20 24(0) 8 20 24
|-------------------------------|
************************************************************************/
calcEndTimestamp(((settingStartTime + DAY_TO_MINUTE) * MINUTE_TO_SECOND), tempStateEndTime);
}
} else {
if (AlarmTimerManager::IsWithinTimeInterval(settingStartTime, settingEndTime)) {
/*********************************************************************
for example settingStartTime=11, settingEndTime=16
↓(setting)
xxxxxxxxxx xxxxxxxxxxxx
0 11 16 24(0) 11 16 24
|-----------------------------------|
************************************************************************/
calcEndTimestamp(((settingStartTime + DAY_TO_MINUTE) * MINUTE_TO_SECOND), tempStateEndTime);
} else if (TemporaryColorModeManager::IsWithInPreInterval(settingStartTime, settingEndTime)) {
/*********************************************************************
for example settingStartTime=11, settingEndTime=16
↓(setting)
xxxxxxxxxx xxxxxxxxxxxx
0 11 16 24(0) 11 16 24
|-------------|
************************************************************************/
calcEndTimestamp((settingEndTime * MINUTE_TO_SECOND), tempStateEndTime);
} else {
/*********************************************************************
for example settingStartTime=11, settingEndTime=16
↓(setting)
xxxxxxxxxx xxxxxxxxxxxx
0 11 16 24(0) 11 16 24
|-------------------------------------|
************************************************************************/
calcEndTimestamp(((settingEndTime + DAY_TO_MINUTE) * MINUTE_TO_SECOND), tempStateEndTime);
}
}
}
bool TemporaryColorModeManager::IsWithInPreInterval(const int32_t startTime, const int32_t endTime)
{
std::time_t timestamp = std::time(nullptr);
if (timestamp == static_cast<std::time_t>(-1)) {
LOGE("fail to get timestamp");
return false;
}
std::tm* nowTime = std::localtime(&timestamp);
int32_t totalMinutes { 0 };
if (nowTime != nullptr) {
totalMinutes = static_cast<int32_t>(nowTime->tm_hour * HOUR_TO_MINUTE + nowTime->tm_min);
}
if (totalMinutes <= startTime) {
return true;
}
return false;
}
void TemporaryColorModeManager::SaveTempColorModeInfo(const int32_t userId)
{
TempColorModeInfo info;
{
std::lock_guard guard(multiUserTempColorModeMapMutex_);
info = multiUserTempColorModeMap_[userId];
}
SetParameterWrap(TemporaryColorModeAssignUser(userId), info.tempColorMode == TempColorModeType::ColorModeNormal
? TEMPORARY_COLOR_MODE_NORMAL_STRING
: TEMPORARY_COLOR_MODE_TEMPORARY_STRING);
LOGI("SaveTempColorModeInfo userId:%{public}d,colorMode:%{public}d", userId,
static_cast<int32_t>(info.tempColorMode));
if (info.tempColorMode == TempColorModeType::ColorModeTemp) {
SetParameterWrap(TemporaryStateStartTimeAssignUser(userId), std::to_string(info.keepTemporaryStateStartTime));
SetParameterWrap(TemporaryStateEndTimeAssignUser(userId), std::to_string(info.keepTemporaryStateEndTime));
LOGI("SaveTempColorModeInfo keepStartTime:%{public}" PRId64 ",keepEndTime:%{public}" PRId64,
info.keepTemporaryStateStartTime, info.keepTemporaryStateEndTime);
}
}
} // namespace OHOS::ArkUi::UiAppearance
@@ -0,0 +1,71 @@
/*
* Copyright (c) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <functional>
#include <vector>
#include <mutex>
#include "screen_switch_operator_manager.h"
namespace {
constexpr int32_t USER100 = 100;
}
namespace OHOS::ArkUi::UiAppearance {
bool ScreenSwitchOperatorManager::IsScreenOn()
{
std::lock_guard guard(screenSwitchMutex_);
return screenSwitch_ == ScreenSwitchType::SCREEN_ON;
}
bool ScreenSwitchOperatorManager::IsScreenOff()
{
std::lock_guard guard(screenSwitchMutex_);
return screenSwitch_ == ScreenSwitchType::SCREEN_OFF;
}
void ScreenSwitchOperatorManager::SetScreenOn()
{
std::lock_guard guard(screenSwitchMutex_);
screenSwitch_ = ScreenSwitchType::SCREEN_ON;
}
void ScreenSwitchOperatorManager::SetScreenOff()
{
std::lock_guard guard(screenSwitchMutex_);
screenSwitch_ = ScreenSwitchType::SCREEN_OFF;
}
void ScreenSwitchOperatorManager::ResetScreenOffOperateInfo()
{
std::lock_guard guard(screenOffOperateInfoMutex_);
screenOffOperateInfo_.screenOffOperator = ScreenOffOperateType::NONE;
screenOffOperateInfo_.userId = USER100;
}
void ScreenSwitchOperatorManager::SetScreenOffOperateInfo(const bool switchToDark, const int32_t userId)
{
std::lock_guard guard(screenOffOperateInfoMutex_);
screenOffOperateInfo_.screenOffOperator =
switchToDark ? ScreenOffOperateType::SWITCH_TO_DARK : ScreenOffOperateType::SWITCH_TO_LIGHT;
screenOffOperateInfo_.userId = userId;
}
void ScreenSwitchOperatorManager::GetScreenOffOperateInfo(bool &switchToDark, int32_t &userId)
{
std::lock_guard guard(screenOffOperateInfoMutex_);
userId = screenOffOperateInfo_.userId;
switchToDark = screenOffOperateInfo_.screenOffOperator == ScreenOffOperateType::SWITCH_TO_DARK ? true : false;
}
bool ScreenSwitchOperatorManager::HaveScreenOffOperate()
{
std::lock_guard guard(screenOffOperateInfoMutex_);
return screenOffOperateInfo_.screenOffOperator != ScreenOffOperateType::NONE;
}
} // namespace OHOS::ArkUi::UiAppearance
+16 -41
View File
@@ -26,9 +26,9 @@
#include "iservice_registry.h"
#include "matching_skills.h"
#include "os_account_manager.h"
#include "syspara/parameter.h"
#include "system_ability_definition.h"
#include "ui_appearance_log.h"
#include "parameter_wrap.h"
namespace {
static const std::string LIGHT = "light";
@@ -54,10 +54,9 @@ const static std::string NOT_FIRST_UPGRADE = "0";
namespace OHOS {
namespace ArkUi::UiAppearance {
UiAppearanceEventSubscriber::UiAppearanceEventSubscriber(
const EventFwk::CommonEventSubscribeInfo& subscriberInfo,
const std::function<void(const int32_t)>& userSwitchCallback): EventFwk::CommonEventSubscriber(subscriberInfo),
userSwitchCallback_(userSwitchCallback)
UiAppearanceEventSubscriber::UiAppearanceEventSubscriber(const EventFwk::CommonEventSubscribeInfo& subscriberInfo,
const std::function<void(const int32_t)>& userSwitchCallback)
: EventFwk::CommonEventSubscriber(subscriberInfo), userSwitchCallback_(userSwitchCallback)
{}
void UiAppearanceEventSubscriber::OnReceiveEvent(const EventFwk::CommonEventData& data)
@@ -76,6 +75,10 @@ void UiAppearanceEventSubscriber::OnReceiveEvent(const EventFwk::CommonEventData
TimeChangeCallback();
} else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_BOOT_COMPLETED) {
BootCompetedCallback();
} else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF) {
DarkModeManager::GetInstance().ScreenOffCallback();
} else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON) {
DarkModeManager::GetInstance().ScreenOnCallback();
}
}
@@ -243,7 +246,6 @@ void UiAppearanceAbility::DoInitProcess()
std::lock_guard<std::mutex> guard(usersParamMutex_);
usersParam_[userId] = tmpParam;
}
LOGI("init userId:%{public}d, darkMode:%{public}s, fontSize:%{public}s, fontWeight:%{public}s", userId,
darkValue.c_str(), fontSize.c_str(), fontWeight.c_str());
}
@@ -302,7 +304,7 @@ void UiAppearanceAbility::UserSwitchFunc(const int32_t userId)
}
bool isForceUpdate = false;
if (code == ERR_OK) {
if (code == ERR_OK && manager.IsColorModeNormal(userId)) {
DarkMode darkMode = isDarkMode ? ALWAYS_DARK : ALWAYS_LIGHT;
std::lock_guard<std::mutex> guard(usersParamMutex_);
if (usersParam_[userId].darkMode != darkMode) {
@@ -321,12 +323,13 @@ void UiAppearanceAbility::SubscribeCommonEvent()
matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED);
matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_TIME_CHANGED);
matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED);
matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON);
matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF);
EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
subscribeInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON);
uiAppearanceEventSubscriber_ = std::make_shared<UiAppearanceEventSubscriber>(
subscribeInfo,
[this](const int32_t userId) { UserSwitchFunc(userId); });
subscribeInfo, [this](const int32_t userId) { UserSwitchFunc(userId); });
bool subResult = EventFwk::CommonEventManager::SubscribeCommonEvent(uiAppearanceEventSubscriber_);
if (!subResult) {
LOGW("subscribe user switch event error");
@@ -348,9 +351,8 @@ void UiAppearanceAbility::OnAddSystemAbility(int32_t systemAbilityId, const std:
return false;
};
isNeedDoCompatibleProcess_ = checkIfFirstUpgrade();
DarkModeManager::GetInstance().Initialize([this](bool isDarkMode, int32_t userId) {
UpdateDarkModeCallback(isDarkMode, userId);
});
DarkModeManager::GetInstance().Initialize(
[this](bool isDarkMode, int32_t userId) { UpdateDarkModeCallback(isDarkMode, userId); });
SubscribeCommonEvent();
if (isNeedDoCompatibleProcess_ && !GetUserIds().empty()) {
DoCompatibleProcess();
@@ -403,35 +405,6 @@ std::string UiAppearanceAbility::FontWeightScaleParamAssignUser(const int32_t us
return FONT_WEIGHT_SCAL_FOR_NONE + std::to_string(userId);
}
bool UiAppearanceAbility::GetParameterWrap(
const std::string& paramName, std::string& value, const std::string& defaultValue)
{
char buf[256] = { 0 };
auto res = GetParameter(paramName.c_str(), defaultValue.c_str(), buf, sizeof(buf));
if (res <= 0) {
LOGE("get parameter %{public}s failed", paramName.c_str());
return false;
}
LOGI("get parameter %{public}s:%{public}s", paramName.c_str(), value.c_str());
value = buf;
return true;
}
bool UiAppearanceAbility::GetParameterWrap(const std::string& paramName, std::string& value)
{
const auto defaultValue = value;
return GetParameterWrap(paramName, value, defaultValue);
}
bool UiAppearanceAbility::SetParameterWrap(const std::string& paramName, const std::string& value)
{
auto res = SetParameter(paramName.c_str(), value.c_str());
if (res != 0) {
LOGE("set parameter %{public}s failed", paramName.c_str());
return false;
}
LOGD("set parameter %{public}s:%{public}s", paramName.c_str(), value.c_str());
return true;
}
bool UiAppearanceAbility::UpdateConfiguration(const AppExecFwk::Configuration& configuration, const int32_t userId)
{
auto appManagerInstance = GetAppManagerInstance();
@@ -495,6 +468,8 @@ int32_t UiAppearanceAbility::OnSetDarkMode(const int32_t userId, DarkMode mode)
return SYS_ERR;
}
DarkModeManager::GetInstance().DoSwitchTemporaryColorMode(userId, mode == ALWAYS_DARK ? true : false);
{
std::lock_guard<std::mutex> guard(usersParamMutex_);
usersParam_[userId].darkMode = mode;
+27
View File
@@ -0,0 +1,27 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef UI_APPEARANCE_PARAMETER_WRAP_H
#define UI_APPEARANCE_PARAMETER_WRAP_H
#include <string>
namespace OHOS::ArkUi::UiAppearance {
bool GetParameterWrap(const std::string& paramName, std::string& value, const std::string& defaultValue);
bool GetParameterWrap(const std::string& paramName, std::string& value);
bool SetParameterWrap(const std::string& paramName, const std::string& value);
} // namespace OHOS::ArkUi::UiAppearance
#endif // UI_APPEARANCE_PARAMETER_WRAP_H
+48
View File
@@ -0,0 +1,48 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ui_appearance_log.h"
#include "parameter_wrap.h"
#include "syspara/parameter.h"
namespace OHOS::ArkUi::UiAppearance {
bool GetParameterWrap(const std::string& paramName, std::string& value, const std::string& defaultValue)
{
char buf[256] = { 0 };
auto res = GetParameter(paramName.c_str(), defaultValue.c_str(), buf, sizeof(buf));
if (res <= 0) {
LOGE("get parameter %{public}s failed", paramName.c_str());
return false;
}
LOGI("get parameter %{public}s:%{public}s", paramName.c_str(), value.c_str());
value = buf;
return true;
}
bool GetParameterWrap(const std::string& paramName, std::string& value)
{
const auto defaultValue = value;
return GetParameterWrap(paramName, value, defaultValue);
}
bool SetParameterWrap(const std::string& paramName, const std::string& value)
{
auto res = SetParameter(paramName.c_str(), value.c_str());
if (res != 0) {
LOGE("set parameter %{public}s failed", paramName.c_str());
return false;
}
LOGD("set parameter %{public}s:%{public}s", paramName.c_str(), value.c_str());
return true;
}
} // namespace OHOS::ArkUi::UiAppearance
+3
View File
@@ -24,10 +24,13 @@ ohos_unittest("ui_appearance_test") {
sources = [
"${ui_appearance_services_path}/src/dark_mode_manager.cpp",
"${ui_appearance_services_path}/src/dark_mode_temp_state_manager.cpp",
"${ui_appearance_services_path}/src/screen_switch_operator_manager.cpp",
"${ui_appearance_services_path}/src/ui_appearance_ability.cpp",
"${ui_appearance_services_path}/src/ui_appearance_ability_stub.cpp",
"${ui_appearance_services_utils_path}/src/alarm_timer.cpp",
"${ui_appearance_services_utils_path}/src/alarm_timer_manager.cpp",
"${ui_appearance_services_utils_path}/src/parameter_wrap.cpp",
"${ui_appearance_services_utils_path}/src/setting_data_manager.cpp",
"${ui_appearance_services_utils_path}/src/setting_data_observer.cpp",
"../mock/mock_accesstoken_kit.cpp",
@@ -27,18 +27,29 @@ ohos_unittest("dark_mode_manager_test") {
"${ui_appearance_test_mock_path}/mock_samgr_proxy/",
"${ui_appearance_test_mock_path}/mock_setting_data_manager/",
"${ui_appearance_services_path}/include/",
"${ui_appearance_services_path}/utils/include/",
]
sources = [
"${ui_appearance_services_path}/src/dark_mode_manager.cpp",
"${ui_appearance_services_path}/src/dark_mode_temp_state_manager.cpp",
"${ui_appearance_services_path}/src/screen_switch_operator_manager.cpp",
"${ui_appearance_services_path}/utils/src/parameter_wrap.cpp",
"dark_mode_manager_test.cpp",
]
external_deps = [
"ability_base:configuration",
"ability_runtime:wantagent_innerkits",
"c_utils:utils",
"common_event_service:cesfwk_core",
"common_event_service:cesfwk_innerkits",
"data_share:datashare_consumer",
"googletest:gmock_main",
"googletest:gtest_main",
"hilog:libhilog",
"init:libbegetutil",
"safwk:system_ability_fwk",
]
}