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