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