1db372d24Sopenharmony_ci/* 2db372d24Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 3db372d24Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4db372d24Sopenharmony_ci * you may not use this file except in compliance with the License. 5db372d24Sopenharmony_ci * You may obtain a copy of the License at 6db372d24Sopenharmony_ci * 7db372d24Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8db372d24Sopenharmony_ci * 9db372d24Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10db372d24Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11db372d24Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12db372d24Sopenharmony_ci * See the License for the specific language governing permissions and 13db372d24Sopenharmony_ci * limitations under the License. 14db372d24Sopenharmony_ci */ 15db372d24Sopenharmony_ci 16db372d24Sopenharmony_ci#include "ui_appearance_ability.h" 17db372d24Sopenharmony_ci 18db372d24Sopenharmony_ci#include <string> 19db372d24Sopenharmony_ci 20db372d24Sopenharmony_ci#include "accesstoken_kit.h" 21db372d24Sopenharmony_ci#include "common_event_manager.h" 22db372d24Sopenharmony_ci#include "common_event_support.h" 23db372d24Sopenharmony_ci#include "global_configuration_key.h" 24db372d24Sopenharmony_ci#include "ipc_skeleton.h" 25db372d24Sopenharmony_ci#include "iservice_registry.h" 26db372d24Sopenharmony_ci#include "matching_skills.h" 27db372d24Sopenharmony_ci#include "os_account_manager.h" 28db372d24Sopenharmony_ci#include "syspara/parameter.h" 29db372d24Sopenharmony_ci#include "system_ability_definition.h" 30db372d24Sopenharmony_ci#include "ui_appearance_log.h" 31db372d24Sopenharmony_ci 32db372d24Sopenharmony_cinamespace { 33db372d24Sopenharmony_cistatic const std::string LIGHT = "light"; 34db372d24Sopenharmony_cistatic const std::string DARK = "dark"; 35db372d24Sopenharmony_cistatic const std::string BASE_SCALE = "1"; 36db372d24Sopenharmony_cistatic const std::string PERSIST_DARKMODE_KEY = "persist.ace.darkmode"; 37db372d24Sopenharmony_cistatic const std::string PERMISSION_UPDATE_CONFIGURATION = "ohos.permission.UPDATE_CONFIGURATION"; 38db372d24Sopenharmony_ci// current default accountId = 0, will change when have more user. 39db372d24Sopenharmony_cistatic const std::string FONT_SCAL_FOR_USER0 = "persist.sys.font_scale_for_user0"; 40db372d24Sopenharmony_cistatic const std::string FONT_Weight_SCAL_FOR_USER0 = "persist.sys.font_wght_scale_for_user0"; 41db372d24Sopenharmony_ci 42db372d24Sopenharmony_cistatic const std::string PERSIST_DARKMODE_KEY_FOR_NONE = "persist.ace.darkmode."; 43db372d24Sopenharmony_cistatic const std::string FONT_SCAL_FOR_NONE = "persist.sys.font_scale_for_user."; 44db372d24Sopenharmony_cistatic const std::string FONT_WEIGHT_SCAL_FOR_NONE = "persist.sys.font_wght_scale_for_user."; 45db372d24Sopenharmony_ci 46db372d24Sopenharmony_cistatic const std::string FIRST_INITIALIZATION = "persist.uiAppearance.first_initialization"; 47db372d24Sopenharmony_ciconst static int32_t USER100 = 100; 48db372d24Sopenharmony_ciconst static std::string FIRST_UPGRADE = "1"; 49db372d24Sopenharmony_ciconst static std::string NOT_FIRST_UPGRADE = "0"; 50db372d24Sopenharmony_ci} // namespace 51db372d24Sopenharmony_ci 52db372d24Sopenharmony_cinamespace OHOS { 53db372d24Sopenharmony_cinamespace ArkUi::UiAppearance { 54db372d24Sopenharmony_ci 55db372d24Sopenharmony_ciUserSwitchEventSubscriber::UserSwitchEventSubscriber(const EventFwk::CommonEventSubscribeInfo& subscriberInfo, 56db372d24Sopenharmony_ci const std::function<void(const int32_t)>& userSwitchCallback) 57db372d24Sopenharmony_ci : EventFwk::CommonEventSubscriber(subscriberInfo), userSwitchCallback_(userSwitchCallback) 58db372d24Sopenharmony_ci{} 59db372d24Sopenharmony_ci 60db372d24Sopenharmony_civoid UserSwitchEventSubscriber::OnReceiveEvent(const EventFwk::CommonEventData& data) 61db372d24Sopenharmony_ci{ 62db372d24Sopenharmony_ci const AAFwk::Want& want = data.GetWant(); 63db372d24Sopenharmony_ci std::string action = want.GetAction(); 64db372d24Sopenharmony_ci LOGI("action:%{public}s", action.c_str()); 65db372d24Sopenharmony_ci 66db372d24Sopenharmony_ci if (action == EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED) { 67db372d24Sopenharmony_ci if (userSwitchCallback_ != nullptr) { 68db372d24Sopenharmony_ci userSwitchCallback_(data.GetCode()); 69db372d24Sopenharmony_ci } 70db372d24Sopenharmony_ci } 71db372d24Sopenharmony_ci} 72db372d24Sopenharmony_ci 73db372d24Sopenharmony_ciREGISTER_SYSTEM_ABILITY_BY_ID(UiAppearanceAbility, ARKUI_UI_APPEARANCE_SERVICE_ID, true); 74db372d24Sopenharmony_ci 75db372d24Sopenharmony_ciUiAppearanceAbility::UiAppearanceAbility(int32_t saId, bool runOnCreate) : SystemAbility(saId, runOnCreate) {} 76db372d24Sopenharmony_ci 77db372d24Sopenharmony_cisptr<AppExecFwk::IAppMgr> UiAppearanceAbility::GetAppManagerInstance() 78db372d24Sopenharmony_ci{ 79db372d24Sopenharmony_ci sptr<ISystemAbilityManager> systemAbilityManager = 80db372d24Sopenharmony_ci SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 81db372d24Sopenharmony_ci if (systemAbilityManager == nullptr) { 82db372d24Sopenharmony_ci LOGE("Getting systemAbilityManager failed."); 83db372d24Sopenharmony_ci return nullptr; 84db372d24Sopenharmony_ci } 85db372d24Sopenharmony_ci 86db372d24Sopenharmony_ci sptr<IRemoteObject> appObject = systemAbilityManager->GetSystemAbility(APP_MGR_SERVICE_ID); 87db372d24Sopenharmony_ci if (appObject == nullptr) { 88db372d24Sopenharmony_ci LOGE("Get systemAbility failed."); 89db372d24Sopenharmony_ci return nullptr; 90db372d24Sopenharmony_ci } 91db372d24Sopenharmony_ci 92db372d24Sopenharmony_ci sptr<AppExecFwk::IAppMgr> systemAbility = iface_cast<AppExecFwk::IAppMgr>(appObject); 93db372d24Sopenharmony_ci if (systemAbility == nullptr) { 94db372d24Sopenharmony_ci LOGE("Get AppMgrProxy from SA failed."); 95db372d24Sopenharmony_ci return nullptr; 96db372d24Sopenharmony_ci } 97db372d24Sopenharmony_ci return systemAbility; 98db372d24Sopenharmony_ci} 99db372d24Sopenharmony_ci 100db372d24Sopenharmony_cibool UiAppearanceAbility::VerifyAccessToken(const std::string& permissionName) 101db372d24Sopenharmony_ci{ 102db372d24Sopenharmony_ci auto callerToken = IPCSkeleton::GetCallingTokenID(); 103db372d24Sopenharmony_ci int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken, permissionName); 104db372d24Sopenharmony_ci if (ret == Security::AccessToken::PermissionState::PERMISSION_GRANTED) { 105db372d24Sopenharmony_ci return true; 106db372d24Sopenharmony_ci } 107db372d24Sopenharmony_ci LOGE("permission %{private}s denied, callerToken : %{public}u", permissionName.c_str(), callerToken); 108db372d24Sopenharmony_ci return false; 109db372d24Sopenharmony_ci} 110db372d24Sopenharmony_ci 111db372d24Sopenharmony_civoid UiAppearanceAbility::OnStart() 112db372d24Sopenharmony_ci{ 113db372d24Sopenharmony_ci bool res = Publish(this); // SA registers with SAMGR 114db372d24Sopenharmony_ci if (!res) { 115db372d24Sopenharmony_ci LOGE("publish failed."); 116db372d24Sopenharmony_ci return; 117db372d24Sopenharmony_ci } 118db372d24Sopenharmony_ci 119db372d24Sopenharmony_ci LOGI("AddSystemAbilityListener start."); 120db372d24Sopenharmony_ci AddSystemAbilityListener(APP_MGR_SERVICE_ID); 121db372d24Sopenharmony_ci return; 122db372d24Sopenharmony_ci} 123db372d24Sopenharmony_ci 124db372d24Sopenharmony_civoid UiAppearanceAbility::OnStop() 125db372d24Sopenharmony_ci{ 126db372d24Sopenharmony_ci LOGI("UiAppearanceAbility SA stop."); 127db372d24Sopenharmony_ci} 128db372d24Sopenharmony_ci 129db372d24Sopenharmony_cistd::vector<int32_t> UiAppearanceAbility::GetUserIds() 130db372d24Sopenharmony_ci{ 131db372d24Sopenharmony_ci std::vector<AccountSA::OsAccountInfo> infos; 132db372d24Sopenharmony_ci AccountSA::OsAccountManager::QueryAllCreatedOsAccounts(infos); 133db372d24Sopenharmony_ci std::vector<int32_t> ids; 134db372d24Sopenharmony_ci for (const auto& info : infos) { 135db372d24Sopenharmony_ci ids.push_back(info.GetLocalId()); 136db372d24Sopenharmony_ci } 137db372d24Sopenharmony_ci return ids; 138db372d24Sopenharmony_ci} 139db372d24Sopenharmony_ci 140db372d24Sopenharmony_civoid UiAppearanceAbility::DoCompatibleProcess() 141db372d24Sopenharmony_ci{ 142db372d24Sopenharmony_ci LOGI("DoCompatibleProcess"); 143db372d24Sopenharmony_ci auto getOldParam = [this](const std::string& paramName, std::string& result) { 144db372d24Sopenharmony_ci return GetParameterWrap(paramName, result); 145db372d24Sopenharmony_ci }; 146db372d24Sopenharmony_ci 147db372d24Sopenharmony_ci auto isParamAllreadaySetted = [this](const std::string& paramName) { 148db372d24Sopenharmony_ci std::string value; 149db372d24Sopenharmony_ci return GetParameterWrap(paramName, value); 150db372d24Sopenharmony_ci }; 151db372d24Sopenharmony_ci 152db372d24Sopenharmony_ci const std::vector<int32_t> userIds = GetUserIds(); 153db372d24Sopenharmony_ci std::unique_lock<std::recursive_mutex> guard(usersParamMutex_); 154db372d24Sopenharmony_ci std::string darkMode = LIGHT; 155db372d24Sopenharmony_ci if (getOldParam(PERSIST_DARKMODE_KEY, darkMode)) { 156db372d24Sopenharmony_ci for (auto id : userIds) { 157db372d24Sopenharmony_ci if (isParamAllreadaySetted(DarkModeParamAssignUser(id))) { 158db372d24Sopenharmony_ci continue; 159db372d24Sopenharmony_ci } 160db372d24Sopenharmony_ci SetParameterWrap(DarkModeParamAssignUser(id), darkMode); 161db372d24Sopenharmony_ci } 162db372d24Sopenharmony_ci LOGD(" set darkMode %{public}s", darkMode.c_str()); 163db372d24Sopenharmony_ci } 164db372d24Sopenharmony_ci std::string fontSize = BASE_SCALE; 165db372d24Sopenharmony_ci if (getOldParam(FONT_SCAL_FOR_USER0, fontSize)) { 166db372d24Sopenharmony_ci for (auto id : userIds) { 167db372d24Sopenharmony_ci if (isParamAllreadaySetted(FontScaleParamAssignUser(id))) { 168db372d24Sopenharmony_ci continue; 169db372d24Sopenharmony_ci } 170db372d24Sopenharmony_ci SetParameterWrap(FontScaleParamAssignUser(id), fontSize); 171db372d24Sopenharmony_ci } 172db372d24Sopenharmony_ci LOGD(" set fontSize %{public}s", fontSize.c_str()); 173db372d24Sopenharmony_ci } 174db372d24Sopenharmony_ci std::string fontWeightSize = BASE_SCALE; 175db372d24Sopenharmony_ci if (getOldParam(FONT_Weight_SCAL_FOR_USER0, fontWeightSize)) { 176db372d24Sopenharmony_ci for (auto id : userIds) { 177db372d24Sopenharmony_ci if (isParamAllreadaySetted(FontWeightScaleParamAssignUser(id))) { 178db372d24Sopenharmony_ci continue; 179db372d24Sopenharmony_ci } 180db372d24Sopenharmony_ci SetParameterWrap(FontWeightScaleParamAssignUser(id), fontWeightSize); 181db372d24Sopenharmony_ci } 182db372d24Sopenharmony_ci LOGD(" set fontWeightSize %{public}s", fontWeightSize.c_str()); 183db372d24Sopenharmony_ci } 184db372d24Sopenharmony_ci SetParameterWrap(FIRST_INITIALIZATION, "0"); 185db372d24Sopenharmony_ci isNeedDoCompatibleProcess_ = false; 186db372d24Sopenharmony_ci} 187db372d24Sopenharmony_ci 188db372d24Sopenharmony_civoid UiAppearanceAbility::DoInitProcess() 189db372d24Sopenharmony_ci{ 190db372d24Sopenharmony_ci LOGI("DoInitProcess"); 191db372d24Sopenharmony_ci const std::vector<int32_t> userIds = GetUserIds(); 192db372d24Sopenharmony_ci for (auto userId : userIds) { 193db372d24Sopenharmony_ci std::string darkValue = LIGHT; 194db372d24Sopenharmony_ci GetParameterWrap(DarkModeParamAssignUser(userId), darkValue); 195db372d24Sopenharmony_ci 196db372d24Sopenharmony_ci std::string fontSize = BASE_SCALE; 197db372d24Sopenharmony_ci GetParameterWrap(FontScaleParamAssignUser(userId), fontSize); 198db372d24Sopenharmony_ci 199db372d24Sopenharmony_ci std::string fontWeight = BASE_SCALE; 200db372d24Sopenharmony_ci GetParameterWrap(FontWeightScaleParamAssignUser(userId), fontWeight); 201db372d24Sopenharmony_ci 202db372d24Sopenharmony_ci UiAppearanceParam tmpParam; 203db372d24Sopenharmony_ci tmpParam.darkMode = darkValue == DARK ? DarkMode::ALWAYS_DARK : DarkMode::ALWAYS_LIGHT; 204db372d24Sopenharmony_ci tmpParam.fontScale = fontSize; 205db372d24Sopenharmony_ci tmpParam.fontWeightScale = fontWeight; 206db372d24Sopenharmony_ci usersParam_[userId] = tmpParam; 207db372d24Sopenharmony_ci } 208db372d24Sopenharmony_ci isInitializationFinished_ = true; 209db372d24Sopenharmony_ci} 210db372d24Sopenharmony_ci 211db372d24Sopenharmony_civoid UiAppearanceAbility::UpdateCurrentUserConfiguration(const int32_t userId) 212db372d24Sopenharmony_ci{ 213db372d24Sopenharmony_ci UiAppearanceParam tmpParam = usersParam_[userId]; 214db372d24Sopenharmony_ci AppExecFwk::Configuration config; 215db372d24Sopenharmony_ci config.AddItem( 216db372d24Sopenharmony_ci AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE, tmpParam.darkMode == DarkMode::ALWAYS_DARK ? DARK : LIGHT); 217db372d24Sopenharmony_ci config.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_FONT_SIZE_SCALE, tmpParam.fontScale); 218db372d24Sopenharmony_ci config.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_FONT_WEIGHT_SCALE, tmpParam.fontWeightScale); 219db372d24Sopenharmony_ci 220db372d24Sopenharmony_ci auto appManagerInstance = GetAppManagerInstance(); 221db372d24Sopenharmony_ci if (appManagerInstance != nullptr) { 222db372d24Sopenharmony_ci appManagerInstance->UpdateConfiguration(config, userId); 223db372d24Sopenharmony_ci SetParameterWrap(PERSIST_DARKMODE_KEY, tmpParam.darkMode == DarkMode::ALWAYS_DARK ? DARK : LIGHT); 224db372d24Sopenharmony_ci SetParameterWrap(FONT_SCAL_FOR_USER0, tmpParam.fontScale); 225db372d24Sopenharmony_ci SetParameterWrap(FONT_Weight_SCAL_FOR_USER0, tmpParam.fontWeightScale); 226db372d24Sopenharmony_ci LOGD("user switch update config %{public}s", config.GetName().c_str()); 227db372d24Sopenharmony_ci } 228db372d24Sopenharmony_ci} 229db372d24Sopenharmony_ci 230db372d24Sopenharmony_civoid UiAppearanceAbility::UserSwitchFunc(const int32_t userId) 231db372d24Sopenharmony_ci{ 232db372d24Sopenharmony_ci std::unique_lock<std::recursive_mutex> guard(usersParamMutex_); 233db372d24Sopenharmony_ci if (isNeedDoCompatibleProcess_) { 234db372d24Sopenharmony_ci DoCompatibleProcess(); 235db372d24Sopenharmony_ci } 236db372d24Sopenharmony_ci if (!isInitializationFinished_) { 237db372d24Sopenharmony_ci DoInitProcess(); 238db372d24Sopenharmony_ci } 239db372d24Sopenharmony_ci UpdateCurrentUserConfiguration(userId); 240db372d24Sopenharmony_ci} 241db372d24Sopenharmony_ci 242db372d24Sopenharmony_civoid UiAppearanceAbility::SubscribeUserSwitchEvent() 243db372d24Sopenharmony_ci{ 244db372d24Sopenharmony_ci EventFwk::MatchingSkills matchingSkills; 245db372d24Sopenharmony_ci matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED); 246db372d24Sopenharmony_ci EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills); 247db372d24Sopenharmony_ci subscribeInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON); 248db372d24Sopenharmony_ci 249db372d24Sopenharmony_ci userSwitchSubscriber_ = std::make_shared<UserSwitchEventSubscriber>( 250db372d24Sopenharmony_ci subscribeInfo, [this](const int32_t userId) { UserSwitchFunc(userId); }); 251db372d24Sopenharmony_ci bool subResult = EventFwk::CommonEventManager::SubscribeCommonEvent(userSwitchSubscriber_); 252db372d24Sopenharmony_ci if (!subResult) { 253db372d24Sopenharmony_ci LOGW("subscribe user switch event error"); 254db372d24Sopenharmony_ci } 255db372d24Sopenharmony_ci} 256db372d24Sopenharmony_ci 257db372d24Sopenharmony_civoid UiAppearanceAbility::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId) 258db372d24Sopenharmony_ci{ 259db372d24Sopenharmony_ci if (systemAbilityId != APP_MGR_SERVICE_ID) { 260db372d24Sopenharmony_ci return; 261db372d24Sopenharmony_ci } 262db372d24Sopenharmony_ci 263db372d24Sopenharmony_ci auto checkIfFirstUpgrade = [this]() { 264db372d24Sopenharmony_ci std::string initFlag = NOT_FIRST_UPGRADE; 265db372d24Sopenharmony_ci GetParameterWrap(FIRST_INITIALIZATION, initFlag); 266db372d24Sopenharmony_ci if (initFlag == FIRST_UPGRADE) { 267db372d24Sopenharmony_ci return true; 268db372d24Sopenharmony_ci } 269db372d24Sopenharmony_ci return false; 270db372d24Sopenharmony_ci }; 271db372d24Sopenharmony_ci isNeedDoCompatibleProcess_ = checkIfFirstUpgrade(); 272db372d24Sopenharmony_ci SubscribeUserSwitchEvent(); 273db372d24Sopenharmony_ci std::unique_lock<std::recursive_mutex> guard(usersParamMutex_); 274db372d24Sopenharmony_ci if (isNeedDoCompatibleProcess_ && !GetUserIds().empty()) { 275db372d24Sopenharmony_ci DoCompatibleProcess(); 276db372d24Sopenharmony_ci } 277db372d24Sopenharmony_ci 278db372d24Sopenharmony_ci if (!isInitializationFinished_ && !GetUserIds().empty()) { 279db372d24Sopenharmony_ci DoInitProcess(); 280db372d24Sopenharmony_ci int32_t userId = USER100; 281db372d24Sopenharmony_ci auto errCode = AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(userId); 282db372d24Sopenharmony_ci if (errCode != 0) { 283db372d24Sopenharmony_ci LOGW("GetForegroundOsAccountLocalId error: %{public}d.", errCode); 284db372d24Sopenharmony_ci userId = USER100; 285db372d24Sopenharmony_ci } 286db372d24Sopenharmony_ci UpdateCurrentUserConfiguration(userId); 287db372d24Sopenharmony_ci } 288db372d24Sopenharmony_ci} 289db372d24Sopenharmony_ci 290db372d24Sopenharmony_civoid UiAppearanceAbility::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId) 291db372d24Sopenharmony_ci{ 292db372d24Sopenharmony_ci LOGI("systemAbilityId = %{public}d removed.", systemAbilityId); 293db372d24Sopenharmony_ci} 294db372d24Sopenharmony_ci 295db372d24Sopenharmony_ciint32_t UiAppearanceAbility::GetCallingUserId() 296db372d24Sopenharmony_ci{ 297db372d24Sopenharmony_ci const static int32_t UID_TRANSFORM_DIVISOR = 200000; 298db372d24Sopenharmony_ci 299db372d24Sopenharmony_ci LOGD("CallingUid = %{public}d", OHOS::IPCSkeleton::GetCallingUid()); 300db372d24Sopenharmony_ci int32_t userId = OHOS::IPCSkeleton::GetCallingUid() / UID_TRANSFORM_DIVISOR; 301db372d24Sopenharmony_ci if (userId == 0) { 302db372d24Sopenharmony_ci auto errNo = AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(userId); 303db372d24Sopenharmony_ci if (errNo != 0) { 304db372d24Sopenharmony_ci LOGE("CallingUid = %{public}d, GetForegroundOsAccountLocalId error:%{public}d", 305db372d24Sopenharmony_ci OHOS::IPCSkeleton::GetCallingUid(), errNo); 306db372d24Sopenharmony_ci userId = USER100; 307db372d24Sopenharmony_ci } 308db372d24Sopenharmony_ci } 309db372d24Sopenharmony_ci return userId; 310db372d24Sopenharmony_ci} 311db372d24Sopenharmony_ci 312db372d24Sopenharmony_cistd::string UiAppearanceAbility::DarkModeParamAssignUser(const int32_t userId) 313db372d24Sopenharmony_ci{ 314db372d24Sopenharmony_ci return PERSIST_DARKMODE_KEY_FOR_NONE + std::to_string(userId); 315db372d24Sopenharmony_ci} 316db372d24Sopenharmony_cistd::string UiAppearanceAbility::FontScaleParamAssignUser(const int32_t userId) 317db372d24Sopenharmony_ci{ 318db372d24Sopenharmony_ci return FONT_SCAL_FOR_NONE + std::to_string(userId); 319db372d24Sopenharmony_ci} 320db372d24Sopenharmony_cistd::string UiAppearanceAbility::FontWeightScaleParamAssignUser(const int32_t userId) 321db372d24Sopenharmony_ci{ 322db372d24Sopenharmony_ci return FONT_WEIGHT_SCAL_FOR_NONE + std::to_string(userId); 323db372d24Sopenharmony_ci} 324db372d24Sopenharmony_cibool UiAppearanceAbility::IsUserExist(const int32_t userId) 325db372d24Sopenharmony_ci{ 326db372d24Sopenharmony_ci std::unique_lock<std::recursive_mutex> guard(usersParamMutex_); 327db372d24Sopenharmony_ci return usersParam_.find(userId) != usersParam_.end(); 328db372d24Sopenharmony_ci} 329db372d24Sopenharmony_ci 330db372d24Sopenharmony_cibool UiAppearanceAbility::GetParameterWrap( 331db372d24Sopenharmony_ci const std::string& paramName, std::string& value, const std::string& defaultValue) 332db372d24Sopenharmony_ci{ 333db372d24Sopenharmony_ci char buf[256] = { 0 }; 334db372d24Sopenharmony_ci auto res = GetParameter(paramName.c_str(), defaultValue.c_str(), buf, sizeof(buf)); 335db372d24Sopenharmony_ci if (res <= 0) { 336db372d24Sopenharmony_ci LOGE("get parameter %{public}s failed", paramName.c_str()); 337db372d24Sopenharmony_ci return false; 338db372d24Sopenharmony_ci } 339db372d24Sopenharmony_ci LOGD("get parameter %{public}s:%{public}s", paramName.c_str(), value.c_str()); 340db372d24Sopenharmony_ci value = buf; 341db372d24Sopenharmony_ci return true; 342db372d24Sopenharmony_ci} 343db372d24Sopenharmony_cibool UiAppearanceAbility::GetParameterWrap(const std::string& paramName, std::string& value) 344db372d24Sopenharmony_ci{ 345db372d24Sopenharmony_ci const auto defaultValue = value; 346db372d24Sopenharmony_ci return GetParameterWrap(paramName, value, defaultValue); 347db372d24Sopenharmony_ci} 348db372d24Sopenharmony_cibool UiAppearanceAbility::SetParameterWrap(const std::string& paramName, const std::string& value) 349db372d24Sopenharmony_ci{ 350db372d24Sopenharmony_ci auto res = SetParameter(paramName.c_str(), value.c_str()); 351db372d24Sopenharmony_ci if (res != 0) { 352db372d24Sopenharmony_ci LOGE("set parameter %{public}s failed", paramName.c_str()); 353db372d24Sopenharmony_ci return false; 354db372d24Sopenharmony_ci } 355db372d24Sopenharmony_ci LOGD("set parameter %{public}s:%{public}s", paramName.c_str(), value.c_str()); 356db372d24Sopenharmony_ci return true; 357db372d24Sopenharmony_ci} 358db372d24Sopenharmony_ci 359db372d24Sopenharmony_cibool UiAppearanceAbility::UpdateConfiguration(const AppExecFwk::Configuration& configuration, const int32_t userId) 360db372d24Sopenharmony_ci{ 361db372d24Sopenharmony_ci auto appManagerInstance = GetAppManagerInstance(); 362db372d24Sopenharmony_ci if (appManagerInstance == nullptr) { 363db372d24Sopenharmony_ci LOGE("Get app manager proxy failed."); 364db372d24Sopenharmony_ci return false; 365db372d24Sopenharmony_ci } 366db372d24Sopenharmony_ci 367db372d24Sopenharmony_ci LOGI("update Configuration start,userId:%{public}d config = %{public}s.", userId, configuration.GetName().c_str()); 368db372d24Sopenharmony_ci auto errcode = appManagerInstance->UpdateConfiguration(configuration, userId); 369db372d24Sopenharmony_ci if (errcode != 0) { 370db372d24Sopenharmony_ci AppExecFwk::Configuration config; 371db372d24Sopenharmony_ci auto retVal = appManagerInstance->GetConfiguration(config); 372db372d24Sopenharmony_ci if (retVal != 0) { 373db372d24Sopenharmony_ci LOGE("get configuration failed, update error, error is %{public}d.", retVal); 374db372d24Sopenharmony_ci return false; 375db372d24Sopenharmony_ci } 376db372d24Sopenharmony_ci std::vector<std::string> diffVe; 377db372d24Sopenharmony_ci config.CompareDifferent(diffVe, configuration); 378db372d24Sopenharmony_ci 379db372d24Sopenharmony_ci if (!diffVe.empty()) { 380db372d24Sopenharmony_ci LOGE("update configuration failed, errcode = %{public}d.", errcode); 381db372d24Sopenharmony_ci return false; 382db372d24Sopenharmony_ci } else { 383db372d24Sopenharmony_ci LOGW("uiappearance is different against configuration. Forced to use the configuration, error is " 384db372d24Sopenharmony_ci "%{public}d.", 385db372d24Sopenharmony_ci errcode); 386db372d24Sopenharmony_ci } 387db372d24Sopenharmony_ci } 388db372d24Sopenharmony_ci return true; 389db372d24Sopenharmony_ci} 390db372d24Sopenharmony_ci 391db372d24Sopenharmony_ciint32_t UiAppearanceAbility::OnSetDarkMode(const int32_t userId, DarkMode mode) 392db372d24Sopenharmony_ci{ 393db372d24Sopenharmony_ci bool ret = false; 394db372d24Sopenharmony_ci std::string paramValue; 395db372d24Sopenharmony_ci AppExecFwk::Configuration config; 396db372d24Sopenharmony_ci switch (mode) { 397db372d24Sopenharmony_ci case ALWAYS_LIGHT: { 398db372d24Sopenharmony_ci ret = config.AddItem( 399db372d24Sopenharmony_ci AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE, AppExecFwk::ConfigurationInner::COLOR_MODE_LIGHT); 400db372d24Sopenharmony_ci paramValue.assign(LIGHT); 401db372d24Sopenharmony_ci break; 402db372d24Sopenharmony_ci } 403db372d24Sopenharmony_ci case ALWAYS_DARK: { 404db372d24Sopenharmony_ci ret = config.AddItem( 405db372d24Sopenharmony_ci AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE, AppExecFwk::ConfigurationInner::COLOR_MODE_DARK); 406db372d24Sopenharmony_ci paramValue.assign(DARK); 407db372d24Sopenharmony_ci break; 408db372d24Sopenharmony_ci } 409db372d24Sopenharmony_ci default: 410db372d24Sopenharmony_ci break; 411db372d24Sopenharmony_ci } 412db372d24Sopenharmony_ci if (!ret) { 413db372d24Sopenharmony_ci LOGE("AddItem failed, mode = %{public}d", mode); 414db372d24Sopenharmony_ci return INVALID_ARG; 415db372d24Sopenharmony_ci } 416db372d24Sopenharmony_ci 417db372d24Sopenharmony_ci if (!UpdateConfiguration(config, userId)) { 418db372d24Sopenharmony_ci return SYS_ERR; 419db372d24Sopenharmony_ci } 420db372d24Sopenharmony_ci 421db372d24Sopenharmony_ci std::unique_lock<std::recursive_mutex> guard(usersParamMutex_); 422db372d24Sopenharmony_ci if (IsUserExist(userId)) { 423db372d24Sopenharmony_ci usersParam_[userId].darkMode = mode; 424db372d24Sopenharmony_ci } else { 425db372d24Sopenharmony_ci UiAppearanceParam tmpParam; 426db372d24Sopenharmony_ci tmpParam.darkMode = mode; 427db372d24Sopenharmony_ci usersParam_[userId] = tmpParam; 428db372d24Sopenharmony_ci } 429db372d24Sopenharmony_ci 430db372d24Sopenharmony_ci SetParameterWrap(PERSIST_DARKMODE_KEY, paramValue); 431db372d24Sopenharmony_ci 432db372d24Sopenharmony_ci // persist to file: etc/para/ui_appearance.para 433db372d24Sopenharmony_ci auto isSetPara = SetParameterWrap(DarkModeParamAssignUser(userId), paramValue); 434db372d24Sopenharmony_ci if (!isSetPara) { 435db372d24Sopenharmony_ci LOGE("set parameter failed"); 436db372d24Sopenharmony_ci return SYS_ERR; 437db372d24Sopenharmony_ci } 438db372d24Sopenharmony_ci return SUCCEEDED; 439db372d24Sopenharmony_ci} 440db372d24Sopenharmony_ci 441db372d24Sopenharmony_ciint32_t UiAppearanceAbility::SetDarkMode(DarkMode mode) 442db372d24Sopenharmony_ci{ 443db372d24Sopenharmony_ci // Verify permissions 444db372d24Sopenharmony_ci auto isCallingPerm = VerifyAccessToken(PERMISSION_UPDATE_CONFIGURATION); 445db372d24Sopenharmony_ci if (!isCallingPerm) { 446db372d24Sopenharmony_ci LOGE("permission verification failed"); 447db372d24Sopenharmony_ci return PERMISSION_ERR; 448db372d24Sopenharmony_ci } 449db372d24Sopenharmony_ci std::unique_lock<std::recursive_mutex> guard(usersParamMutex_); 450db372d24Sopenharmony_ci auto userId = GetCallingUserId(); 451db372d24Sopenharmony_ci auto it = usersParam_.find(userId); 452db372d24Sopenharmony_ci if (it != usersParam_.end()) { 453db372d24Sopenharmony_ci if (mode != it->second.darkMode) { 454db372d24Sopenharmony_ci return OnSetDarkMode(userId, mode); 455db372d24Sopenharmony_ci } else { 456db372d24Sopenharmony_ci LOGW("current color mode is %{public}d, no need to change", mode); 457db372d24Sopenharmony_ci } 458db372d24Sopenharmony_ci } else { 459db372d24Sopenharmony_ci return OnSetDarkMode(userId, mode); 460db372d24Sopenharmony_ci } 461db372d24Sopenharmony_ci 462db372d24Sopenharmony_ci return SYS_ERR; 463db372d24Sopenharmony_ci} 464db372d24Sopenharmony_ci 465db372d24Sopenharmony_ciUiAppearanceAbility::DarkMode UiAppearanceAbility::InitGetDarkMode(const int32_t userId) 466db372d24Sopenharmony_ci{ 467db372d24Sopenharmony_ci std::string valueGet = LIGHT; 468db372d24Sopenharmony_ci 469db372d24Sopenharmony_ci // LIGHT is the default. 470db372d24Sopenharmony_ci auto res = GetParameterWrap(DarkModeParamAssignUser(userId), valueGet); 471db372d24Sopenharmony_ci if (!res) { 472db372d24Sopenharmony_ci return ALWAYS_LIGHT; 473db372d24Sopenharmony_ci } 474db372d24Sopenharmony_ci if (valueGet == DARK) { 475db372d24Sopenharmony_ci LOGI("current color mode is dark."); 476db372d24Sopenharmony_ci return ALWAYS_DARK; 477db372d24Sopenharmony_ci } else if (valueGet == LIGHT) { 478db372d24Sopenharmony_ci LOGI("current color mode is light."); 479db372d24Sopenharmony_ci return ALWAYS_LIGHT; 480db372d24Sopenharmony_ci } 481db372d24Sopenharmony_ci return ALWAYS_LIGHT; 482db372d24Sopenharmony_ci} 483db372d24Sopenharmony_ci 484db372d24Sopenharmony_ciint32_t UiAppearanceAbility::GetDarkMode() 485db372d24Sopenharmony_ci{ 486db372d24Sopenharmony_ci auto isCallingPerm = VerifyAccessToken(PERMISSION_UPDATE_CONFIGURATION); 487db372d24Sopenharmony_ci if (!isCallingPerm) { 488db372d24Sopenharmony_ci LOGE("permission verification failed"); 489db372d24Sopenharmony_ci return PERMISSION_ERR; 490db372d24Sopenharmony_ci } 491db372d24Sopenharmony_ci std::unique_lock<std::recursive_mutex> guard(usersParamMutex_); 492db372d24Sopenharmony_ci auto it = usersParam_.find(GetCallingUserId()); 493db372d24Sopenharmony_ci if (it != usersParam_.end()) { 494db372d24Sopenharmony_ci return it->second.darkMode; 495db372d24Sopenharmony_ci } 496db372d24Sopenharmony_ci return DarkMode::ALWAYS_LIGHT; 497db372d24Sopenharmony_ci} 498db372d24Sopenharmony_ci 499db372d24Sopenharmony_ciint32_t UiAppearanceAbility::OnSetFontScale(const int32_t userId, std::string& fontScale) 500db372d24Sopenharmony_ci{ 501db372d24Sopenharmony_ci bool ret = false; 502db372d24Sopenharmony_ci AppExecFwk::Configuration config; 503db372d24Sopenharmony_ci ret = config.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_FONT_SIZE_SCALE, fontScale); 504db372d24Sopenharmony_ci if (!ret) { 505db372d24Sopenharmony_ci LOGE("AddItem failed, fontScale = %{public}s", fontScale.c_str()); 506db372d24Sopenharmony_ci return INVALID_ARG; 507db372d24Sopenharmony_ci } 508db372d24Sopenharmony_ci if (!UpdateConfiguration(config, userId)) { 509db372d24Sopenharmony_ci return SYS_ERR; 510db372d24Sopenharmony_ci } 511db372d24Sopenharmony_ci 512db372d24Sopenharmony_ci std::unique_lock<std::recursive_mutex> guard(usersParamMutex_); 513db372d24Sopenharmony_ci if (IsUserExist(userId)) { 514db372d24Sopenharmony_ci usersParam_[userId].fontScale = fontScale; 515db372d24Sopenharmony_ci } else { 516db372d24Sopenharmony_ci UiAppearanceParam tmpParam; 517db372d24Sopenharmony_ci tmpParam.fontScale = fontScale; 518db372d24Sopenharmony_ci usersParam_[userId] = tmpParam; 519db372d24Sopenharmony_ci } 520db372d24Sopenharmony_ci 521db372d24Sopenharmony_ci SetParameterWrap(FONT_SCAL_FOR_USER0, fontScale); 522db372d24Sopenharmony_ci // persist to file: etc/para/ui_appearance.para 523db372d24Sopenharmony_ci auto isSetPara = SetParameterWrap(FontScaleParamAssignUser(userId), fontScale); 524db372d24Sopenharmony_ci if (!isSetPara) { 525db372d24Sopenharmony_ci LOGE("set parameter failed"); 526db372d24Sopenharmony_ci return SYS_ERR; 527db372d24Sopenharmony_ci } 528db372d24Sopenharmony_ci return SUCCEEDED; 529db372d24Sopenharmony_ci} 530db372d24Sopenharmony_ci 531db372d24Sopenharmony_ciint32_t UiAppearanceAbility::SetFontScale(std::string& fontScale) 532db372d24Sopenharmony_ci{ 533db372d24Sopenharmony_ci // Verify permissions 534db372d24Sopenharmony_ci auto isCallingPerm = VerifyAccessToken(PERMISSION_UPDATE_CONFIGURATION); 535db372d24Sopenharmony_ci if (!isCallingPerm) { 536db372d24Sopenharmony_ci LOGE("permission verification failed"); 537db372d24Sopenharmony_ci return PERMISSION_ERR; 538db372d24Sopenharmony_ci } 539db372d24Sopenharmony_ci if (!fontScale.empty()) { 540db372d24Sopenharmony_ci return OnSetFontScale(GetCallingUserId(), fontScale); 541db372d24Sopenharmony_ci } else { 542db372d24Sopenharmony_ci LOGE("current fontScale is empty!"); 543db372d24Sopenharmony_ci } 544db372d24Sopenharmony_ci return SYS_ERR; 545db372d24Sopenharmony_ci} 546db372d24Sopenharmony_ci 547db372d24Sopenharmony_ciint32_t UiAppearanceAbility::GetFontScale(std::string& fontScale) 548db372d24Sopenharmony_ci{ 549db372d24Sopenharmony_ci auto isCallingPerm = VerifyAccessToken(PERMISSION_UPDATE_CONFIGURATION); 550db372d24Sopenharmony_ci if (!isCallingPerm) { 551db372d24Sopenharmony_ci LOGE("permission verification failed"); 552db372d24Sopenharmony_ci return PERMISSION_ERR; 553db372d24Sopenharmony_ci } 554db372d24Sopenharmony_ci std::unique_lock<std::recursive_mutex> guard(usersParamMutex_); 555db372d24Sopenharmony_ci auto it = usersParam_.find(GetCallingUserId()); 556db372d24Sopenharmony_ci if (it != usersParam_.end()) { 557db372d24Sopenharmony_ci fontScale = it->second.fontScale; 558db372d24Sopenharmony_ci } else { 559db372d24Sopenharmony_ci fontScale = BASE_SCALE; 560db372d24Sopenharmony_ci } 561db372d24Sopenharmony_ci LOGD("get font scale :%{public}s", fontScale.c_str()); 562db372d24Sopenharmony_ci return SUCCEEDED; 563db372d24Sopenharmony_ci} 564db372d24Sopenharmony_ci 565db372d24Sopenharmony_ciint32_t UiAppearanceAbility::OnSetFontWeightScale(const int32_t userId, std::string& fontWeightScale) 566db372d24Sopenharmony_ci{ 567db372d24Sopenharmony_ci bool ret = false; 568db372d24Sopenharmony_ci AppExecFwk::Configuration config; 569db372d24Sopenharmony_ci ret = config.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_FONT_WEIGHT_SCALE, fontWeightScale); 570db372d24Sopenharmony_ci if (!ret) { 571db372d24Sopenharmony_ci LOGE("AddItem failed, fontWeightScale = %{public}s", fontWeightScale.c_str()); 572db372d24Sopenharmony_ci return INVALID_ARG; 573db372d24Sopenharmony_ci } 574db372d24Sopenharmony_ci 575db372d24Sopenharmony_ci if (!UpdateConfiguration(config, userId)) { 576db372d24Sopenharmony_ci return SYS_ERR; 577db372d24Sopenharmony_ci } 578db372d24Sopenharmony_ci std::unique_lock<std::recursive_mutex> guard(usersParamMutex_); 579db372d24Sopenharmony_ci if (IsUserExist(userId)) { 580db372d24Sopenharmony_ci usersParam_[userId].fontWeightScale = fontWeightScale; 581db372d24Sopenharmony_ci } else { 582db372d24Sopenharmony_ci UiAppearanceParam tmpParam; 583db372d24Sopenharmony_ci tmpParam.fontWeightScale = fontWeightScale; 584db372d24Sopenharmony_ci usersParam_[userId] = tmpParam; 585db372d24Sopenharmony_ci } 586db372d24Sopenharmony_ci 587db372d24Sopenharmony_ci SetParameterWrap(FONT_Weight_SCAL_FOR_USER0, fontWeightScale); 588db372d24Sopenharmony_ci 589db372d24Sopenharmony_ci // persist to file: etc/para/ui_appearance.para 590db372d24Sopenharmony_ci auto isSetPara = SetParameterWrap(FontWeightScaleParamAssignUser(userId), fontWeightScale); 591db372d24Sopenharmony_ci if (!isSetPara) { 592db372d24Sopenharmony_ci LOGE("set parameter failed"); 593db372d24Sopenharmony_ci return SYS_ERR; 594db372d24Sopenharmony_ci } 595db372d24Sopenharmony_ci return SUCCEEDED; 596db372d24Sopenharmony_ci} 597db372d24Sopenharmony_ci 598db372d24Sopenharmony_ciint32_t UiAppearanceAbility::SetFontWeightScale(std::string& fontWeightScale) 599db372d24Sopenharmony_ci{ 600db372d24Sopenharmony_ci // Verify permissions 601db372d24Sopenharmony_ci auto isCallingPerm = VerifyAccessToken(PERMISSION_UPDATE_CONFIGURATION); 602db372d24Sopenharmony_ci if (!isCallingPerm) { 603db372d24Sopenharmony_ci LOGE("permission verification failed"); 604db372d24Sopenharmony_ci return PERMISSION_ERR; 605db372d24Sopenharmony_ci } 606db372d24Sopenharmony_ci if (!fontWeightScale.empty()) { 607db372d24Sopenharmony_ci return OnSetFontWeightScale(GetCallingUserId(), fontWeightScale); 608db372d24Sopenharmony_ci } else { 609db372d24Sopenharmony_ci LOGE("current fontWeightScale is empty!"); 610db372d24Sopenharmony_ci } 611db372d24Sopenharmony_ci return SYS_ERR; 612db372d24Sopenharmony_ci} 613db372d24Sopenharmony_ci 614db372d24Sopenharmony_ciint32_t UiAppearanceAbility::GetFontWeightScale(std::string& fontWeightScale) 615db372d24Sopenharmony_ci{ 616db372d24Sopenharmony_ci auto isCallingPerm = VerifyAccessToken(PERMISSION_UPDATE_CONFIGURATION); 617db372d24Sopenharmony_ci if (!isCallingPerm) { 618db372d24Sopenharmony_ci LOGE("permission verification failed"); 619db372d24Sopenharmony_ci return PERMISSION_ERR; 620db372d24Sopenharmony_ci } 621db372d24Sopenharmony_ci std::unique_lock<std::recursive_mutex> guard(usersParamMutex_); 622db372d24Sopenharmony_ci auto it = usersParam_.find(GetCallingUserId()); 623db372d24Sopenharmony_ci if (it != usersParam_.end()) { 624db372d24Sopenharmony_ci fontWeightScale = it->second.fontWeightScale; 625db372d24Sopenharmony_ci } else { 626db372d24Sopenharmony_ci fontWeightScale = BASE_SCALE; 627db372d24Sopenharmony_ci } 628db372d24Sopenharmony_ci LOGD("get font weight scale :%{public}s", fontWeightScale.c_str()); 629db372d24Sopenharmony_ci return SUCCEEDED; 630db372d24Sopenharmony_ci} 631db372d24Sopenharmony_ci 632db372d24Sopenharmony_ci} // namespace ArkUi::UiAppearance 633db372d24Sopenharmony_ci} // namespace OHOS 634