1 /*
2 * Copyright (c) 2022-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "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 "dark_mode_manager.h"
24 #include "global_configuration_key.h"
25 #include "ipc_skeleton.h"
26 #include "iservice_registry.h"
27 #include "matching_skills.h"
28 #include "os_account_manager.h"
29 #include "smart_gesture_manager.h"
30 #include "system_ability_definition.h"
31 #include "ui_appearance_log.h"
32 #include "parameter_wrap.h"
33 #include "background_app_color_switch_settings.h"
34 #include "background_app_info.h"
35 #include "configuration_policy.h"
36
37 namespace {
38 static const std::string LIGHT = "light";
39 static const std::string DARK = "dark";
40 static const std::string BASE_SCALE = "1";
41 static const std::string PERSIST_DARKMODE_KEY = "persist.ace.darkmode";
42 static const std::string PERMISSION_UPDATE_CONFIGURATION = "ohos.permission.UPDATE_CONFIGURATION";
43 // current default accountId = 0, will change when have more user.
44 static const std::string FONT_SCAL_FOR_USER0 = "persist.sys.font_scale_for_user0";
45 static const std::string FONT_Weight_SCAL_FOR_USER0 = "persist.sys.font_wght_scale_for_user0";
46
47 static const std::string PERSIST_DARKMODE_KEY_FOR_NONE = "persist.ace.darkmode.";
48 static const std::string FONT_SCAL_FOR_NONE = "persist.sys.font_scale_for_user.";
49 static const std::string FONT_WEIGHT_SCAL_FOR_NONE = "persist.sys.font_wght_scale_for_user.";
50
51 static const std::string FIRST_INITIALIZATION = "persist.uiAppearance.first_initialization";
52 const static int32_t USER100 = 100;
53 const static int32_t USER0 = 0;
54 const static std::string FIRST_UPGRADE = "1";
55 const static std::string NOT_FIRST_UPGRADE = "0";
56 } // namespace
57
58 namespace OHOS {
59 namespace ArkUi::UiAppearance {
UiAppearanceEventSubscriber(const EventFwk::CommonEventSubscribeInfo & subscriberInfo,const std::function<void (const int32_t)> & userSwitchCallback)60 UiAppearanceEventSubscriber::UiAppearanceEventSubscriber(const EventFwk::CommonEventSubscribeInfo& subscriberInfo,
61 const std::function<void(const int32_t)>& userSwitchCallback)
62 : EventFwk::CommonEventSubscriber(subscriberInfo), userSwitchCallback_(userSwitchCallback)
63 {}
64
OnReceiveEvent(const EventFwk::CommonEventData & data)65 void UiAppearanceEventSubscriber::OnReceiveEvent(const EventFwk::CommonEventData& data)
66 {
67 const AAFwk::Want& want = data.GetWant();
68 std::string action = want.GetAction();
69 LOGI("action:%{public}s", action.c_str());
70
71 if (action == EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED) {
72 if (userSwitchCallback_ != nullptr) {
73 userSwitchCallback_(data.GetCode());
74 }
75 } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_TIME_CHANGED) {
76 TimeChangeCallback();
77 } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED) {
78 TimeChangeCallback();
79 } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_BOOT_COMPLETED) {
80 BootCompetedCallback();
81 } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF) {
82 DarkModeManager::GetInstance().ScreenOffCallback();
83 } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON) {
84 DarkModeManager::GetInstance().ScreenOnCallback();
85 }
86 }
87
TimeChangeCallback()88 void UiAppearanceEventSubscriber::TimeChangeCallback()
89 {
90 DarkModeManager::GetInstance().RestartTimer();
91 }
92
BootCompetedCallback()93 void UiAppearanceEventSubscriber::BootCompetedCallback()
94 {
95 std::call_once(bootCompleteFlag_, [] () {
96 std::vector<int32_t> ids;
97 AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids);
98 int32_t userId;
99 if (ids.empty()) {
100 LOGE("no active user.");
101 userId = USER100;
102 } else {
103 userId = ids[0];
104 }
105 DarkModeManager &manager = DarkModeManager::GetInstance();
106 manager.OnSwitchUser(userId);
107 bool isDarkMode = false;
108 manager.LoadUserSettingData(userId, true, isDarkMode, true);
109 SmartGestureManager &smartGestureManager = SmartGestureManager::GetInstance();
110 smartGestureManager.RegisterSettingDataObserver();
111 smartGestureManager.UpdateSmartGestureInitialValue();
112 });
113 }
114
115 REGISTER_SYSTEM_ABILITY_BY_ID(UiAppearanceAbility, ARKUI_UI_APPEARANCE_SERVICE_ID, true);
116
UiAppearanceAbility(int32_t saId,bool runOnCreate)117 UiAppearanceAbility::UiAppearanceAbility(int32_t saId, bool runOnCreate) : SystemAbility(saId, runOnCreate) {}
118
GetAppManagerInstance()119 sptr<AppExecFwk::IAppMgr> UiAppearanceAbility::GetAppManagerInstance()
120 {
121 sptr<ISystemAbilityManager> systemAbilityManager =
122 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
123 if (systemAbilityManager == nullptr) {
124 LOGE("Getting systemAbilityManager failed.");
125 return nullptr;
126 }
127
128 sptr<IRemoteObject> appObject = systemAbilityManager->GetSystemAbility(APP_MGR_SERVICE_ID);
129 if (appObject == nullptr) {
130 LOGE("Get systemAbility failed.");
131 return nullptr;
132 }
133
134 sptr<AppExecFwk::IAppMgr> systemAbility = iface_cast<AppExecFwk::IAppMgr>(appObject);
135 if (systemAbility == nullptr) {
136 LOGE("Get AppMgrProxy from SA failed.");
137 return nullptr;
138 }
139 return systemAbility;
140 }
141
VerifyAccessToken(const std::string & permissionName)142 bool UiAppearanceAbility::VerifyAccessToken(const std::string& permissionName)
143 {
144 auto callerToken = IPCSkeleton::GetCallingTokenID();
145 int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken, permissionName);
146 if (ret == Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
147 return true;
148 }
149 LOGE("permission %{private}s denied, callerToken : %{public}u", permissionName.c_str(), callerToken);
150 return false;
151 }
152
OnStart()153 void UiAppearanceAbility::OnStart()
154 {
155 bool res = Publish(this); // SA registers with SAMGR
156 if (!res) {
157 LOGE("publish failed.");
158 return;
159 }
160
161 LOGI("AddSystemAbilityListener start.");
162 AddSystemAbilityListener(APP_MGR_SERVICE_ID);
163 return;
164 }
165
OnStop()166 void UiAppearanceAbility::OnStop()
167 {
168 LOGI("UiAppearanceAbility SA stop.");
169 }
170
GetUserIds()171 std::list<int32_t> UiAppearanceAbility::GetUserIds()
172 {
173 std::vector<AccountSA::OsAccountInfo> infos;
174 auto errCode = AccountSA::OsAccountManager::QueryAllCreatedOsAccounts(infos);
175 if (errCode != 0) {
176 LOGW("QueryAllCreatedOsAccounts error: %{public}d.", errCode);
177 return {};
178 }
179 std::list<int32_t> ids;
180 for (const auto& info : infos) {
181 ids.push_back(info.GetLocalId());
182 }
183 return ids;
184 }
185
DoCompatibleProcess()186 void UiAppearanceAbility::DoCompatibleProcess()
187 {
188 LOGI("DoCompatibleProcess");
189 auto getOldParam = [this](const std::string& paramName, std::string& result) {
190 return GetParameterWrap(paramName, result);
191 };
192
193 auto isParamAllreadaySetted = [this](const std::string& paramName) {
194 std::string value;
195 return GetParameterWrap(paramName, value);
196 };
197
198 const std::list<int32_t> userIds = GetUserIds();
199 std::string darkMode = LIGHT;
200 if (getOldParam(PERSIST_DARKMODE_KEY, darkMode)) {
201 for (auto id : userIds) {
202 if (isParamAllreadaySetted(DarkModeParamAssignUser(id))) {
203 continue;
204 }
205 SetParameterWrap(DarkModeParamAssignUser(id), darkMode);
206 LOGI("userId:%{public}d set darkMode %{public}s", id, darkMode.c_str());
207 }
208 }
209 std::string fontSize = BASE_SCALE;
210 if (getOldParam(FONT_SCAL_FOR_USER0, fontSize)) {
211 for (auto id : userIds) {
212 if (isParamAllreadaySetted(FontScaleParamAssignUser(id))) {
213 continue;
214 }
215 SetParameterWrap(FontScaleParamAssignUser(id), fontSize);
216 LOGI("userId:%{public}d set fontSize %{public}s", id, fontSize.c_str());
217 }
218 }
219 std::string fontWeightSize = BASE_SCALE;
220 if (getOldParam(FONT_Weight_SCAL_FOR_USER0, fontWeightSize)) {
221 for (auto id : userIds) {
222 if (isParamAllreadaySetted(FontWeightScaleParamAssignUser(id))) {
223 continue;
224 }
225 SetParameterWrap(FontWeightScaleParamAssignUser(id), fontWeightSize);
226 LOGI("userId:%{public}d set fontWeightSize %{public}s", id, fontWeightSize.c_str());
227 }
228 }
229 SetParameterWrap(FIRST_INITIALIZATION, "0");
230 isNeedDoCompatibleProcess_ = false;
231 }
232
DoInitProcess()233 void UiAppearanceAbility::DoInitProcess()
234 {
235 LOGI("DoInitProcess");
236 BackGroundAppColorSwitchSettings::GetInstance().Initialize();
237 const std::list<int32_t> userIds = GetUserIds();
238 for (auto userId : userIds) {
239 std::string darkValue = LIGHT;
240 GetParameterWrap(DarkModeParamAssignUser(userId), darkValue);
241
242 std::string fontSize = BASE_SCALE;
243 GetParameterWrap(FontScaleParamAssignUser(userId), fontSize);
244
245 std::string fontWeight = BASE_SCALE;
246 GetParameterWrap(FontWeightScaleParamAssignUser(userId), fontWeight);
247
248 UiAppearanceParam tmpParam;
249 tmpParam.darkMode = darkValue == DARK ? DarkMode::ALWAYS_DARK : DarkMode::ALWAYS_LIGHT;
250 tmpParam.fontScale = fontSize;
251 tmpParam.fontWeightScale = fontWeight;
252 {
253 std::lock_guard<std::mutex> guard(usersParamMutex_);
254 usersParam_[userId] = tmpParam;
255 }
256 LOGI("init userId:%{public}d, darkMode:%{public}s, fontSize:%{public}s, fontWeight:%{public}s", userId,
257 darkValue.c_str(), fontSize.c_str(), fontWeight.c_str());
258 }
259 isInitializationFinished_ = true;
260 }
261
UpdateCurrentUserConfiguration(const int32_t userId,const bool isForceUpdate)262 void UiAppearanceAbility::UpdateCurrentUserConfiguration(const int32_t userId, const bool isForceUpdate)
263 {
264 UiAppearanceParam tmpParam;
265 {
266 std::lock_guard<std::mutex> guard(usersParamMutex_);
267 tmpParam = usersParam_[userId];
268 }
269 AppExecFwk::Configuration config;
270 config.AddItem(
271 AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE, tmpParam.darkMode == DarkMode::ALWAYS_DARK ? DARK : LIGHT);
272 config.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_FONT_SIZE_SCALE, tmpParam.fontScale);
273 config.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_FONT_WEIGHT_SCALE, tmpParam.fontWeightScale);
274
275 auto appManagerInstance = GetAppManagerInstance();
276 if (!appManagerInstance) {
277 LOGE("GetAppManagerInstance error userId:%{public}d", userId);
278 return;
279 }
280
281 {
282 std::lock_guard<std::mutex> onceFlagGuard(userSwitchUpdateConfigurationOnceFlagMutex_);
283 if (isForceUpdate ||
284 userSwitchUpdateConfigurationOnceFlag_.find(userId) == userSwitchUpdateConfigurationOnceFlag_.end()) {
285 appManagerInstance->UpdateConfiguration(config, userId);
286 LOGI("update userId:%{public}d configuration:%{public}s", userId, config.GetName().c_str());
287 userSwitchUpdateConfigurationOnceFlag_.insert(userId);
288 } else {
289 appManagerInstance->UpdateConfiguration(config, USER0);
290 LOGI("update userId:%{public}d configuration:%{public}s", USER0, config.GetName().c_str());
291 }
292 }
293
294 SetParameterWrap(PERSIST_DARKMODE_KEY, tmpParam.darkMode == DarkMode::ALWAYS_DARK ? DARK : LIGHT);
295 SetParameterWrap(FONT_SCAL_FOR_USER0, tmpParam.fontScale);
296 SetParameterWrap(FONT_Weight_SCAL_FOR_USER0, tmpParam.fontWeightScale);
297 }
298
UserSwitchFunc(const int32_t userId)299 void UiAppearanceAbility::UserSwitchFunc(const int32_t userId)
300 {
301 DarkModeManager& manager = DarkModeManager::GetInstance();
302 manager.OnSwitchUser(userId);
303 bool isDarkMode = false;
304 int32_t code = manager.LoadUserSettingData(userId, false, isDarkMode, false);
305
306 if (isNeedDoCompatibleProcess_) {
307 DoCompatibleProcess();
308 }
309 if (!isInitializationFinished_) {
310 DoInitProcess();
311 }
312
313 bool isForceUpdate = false;
314 if (code == ERR_OK && manager.IsColorModeNormal(userId)) {
315 DarkMode darkMode = isDarkMode ? ALWAYS_DARK : ALWAYS_LIGHT;
316 std::lock_guard<std::mutex> guard(usersParamMutex_);
317 if (usersParam_[userId].darkMode != darkMode) {
318 usersParam_[userId].darkMode = darkMode;
319 isForceUpdate = true;
320 }
321 }
322
323 UpdateCurrentUserConfiguration(userId, isForceUpdate);
324 }
325
SubscribeCommonEvent()326 void UiAppearanceAbility::SubscribeCommonEvent()
327 {
328 EventFwk::MatchingSkills matchingSkills;
329 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_BOOT_COMPLETED);
330 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED);
331 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_TIME_CHANGED);
332 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED);
333 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON);
334 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF);
335 EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
336 subscribeInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON);
337
338 uiAppearanceEventSubscriber_ = std::make_shared<UiAppearanceEventSubscriber>(
339 subscribeInfo, [this](const int32_t userId) { UserSwitchFunc(userId); });
340 bool subResult = EventFwk::CommonEventManager::SubscribeCommonEvent(uiAppearanceEventSubscriber_);
341 if (!subResult) {
342 LOGW("subscribe user switch event error");
343 }
344 }
345
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)346 void UiAppearanceAbility::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
347 {
348 if (systemAbilityId != APP_MGR_SERVICE_ID) {
349 return;
350 }
351
352 auto checkIfFirstUpgrade = [this]() {
353 std::string initFlag = NOT_FIRST_UPGRADE;
354 GetParameterWrap(FIRST_INITIALIZATION, initFlag);
355 if (initFlag == FIRST_UPGRADE) {
356 return true;
357 }
358 return false;
359 };
360 isNeedDoCompatibleProcess_ = checkIfFirstUpgrade();
361 DarkModeManager::GetInstance().Initialize(
362 [this](bool isDarkMode, int32_t userId) { UpdateDarkModeCallback(isDarkMode, userId); });
363 SmartGestureManager::GetInstance().Initialize(
364 [this](bool isAutoMode, int32_t userId) { UpdateSmartGestureModeCallback(isAutoMode, userId); });
365 SubscribeCommonEvent();
366 if (isNeedDoCompatibleProcess_ && !GetUserIds().empty()) {
367 DoCompatibleProcess();
368 }
369
370 if (!isInitializationFinished_ && !GetUserIds().empty()) {
371 DoInitProcess();
372 int32_t userId = USER100;
373 auto errCode = AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(userId);
374 if (errCode != 0) {
375 LOGW("GetForegroundOsAccountLocalId error: %{public}d.", errCode);
376 userId = USER100;
377 }
378 UpdateCurrentUserConfiguration(userId, false);
379 }
380 }
381
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)382 void UiAppearanceAbility::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
383 {
384 LOGI("systemAbilityId = %{public}d removed.", systemAbilityId);
385 if (systemAbilityId == APP_MGR_SERVICE_ID) {
386 std::lock_guard<std::mutex> onceFlagGuard(userSwitchUpdateConfigurationOnceFlagMutex_);
387 userSwitchUpdateConfigurationOnceFlag_.clear();
388 }
389 }
390
GetCallingUserId()391 int32_t UiAppearanceAbility::GetCallingUserId()
392 {
393 const static int32_t UID_TRANSFORM_DIVISOR = 200000;
394
395 LOGD("CallingUid = %{public}d", OHOS::IPCSkeleton::GetCallingUid());
396 int32_t userId = OHOS::IPCSkeleton::GetCallingUid() / UID_TRANSFORM_DIVISOR;
397 if (userId == 0) {
398 auto errNo = AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(userId);
399 if (errNo != 0) {
400 LOGE("CallingUid = %{public}d, GetForegroundOsAccountLocalId error:%{public}d",
401 OHOS::IPCSkeleton::GetCallingUid(), errNo);
402 userId = USER100;
403 }
404 }
405 return userId;
406 }
407
DarkModeParamAssignUser(const int32_t userId)408 std::string UiAppearanceAbility::DarkModeParamAssignUser(const int32_t userId)
409 {
410 return PERSIST_DARKMODE_KEY_FOR_NONE + std::to_string(userId);
411 }
FontScaleParamAssignUser(const int32_t userId)412 std::string UiAppearanceAbility::FontScaleParamAssignUser(const int32_t userId)
413 {
414 return FONT_SCAL_FOR_NONE + std::to_string(userId);
415 }
FontWeightScaleParamAssignUser(const int32_t userId)416 std::string UiAppearanceAbility::FontWeightScaleParamAssignUser(const int32_t userId)
417 {
418 return FONT_WEIGHT_SCAL_FOR_NONE + std::to_string(userId);
419 }
420
BackGroundAppColorSwitch(sptr<AppExecFwk::IAppMgr> appManagerInstance,const int32_t userId)421 bool UiAppearanceAbility::BackGroundAppColorSwitch(sptr<AppExecFwk::IAppMgr> appManagerInstance, const int32_t userId)
422 {
423 if (!BackGroundAppColorSwitchSettings::GetInstance().IsSupportHotUpdate()) {
424 LOGI("not Support BackGround App Color Switch");
425 return false;
426 }
427
428 std::vector<AppExecFwk::BackgroundAppInfo> backgroundAppInfoVe;
429 for (const auto& whiteListItem : BackGroundAppColorSwitchSettings::GetInstance().GetWhileList()) {
430 AppExecFwk::BackgroundAppInfo appInfo;
431 appInfo.bandleName = whiteListItem;
432 appInfo.appIndex = 0;
433 backgroundAppInfoVe.push_back(appInfo);
434 }
435
436 if (backgroundAppInfoVe.empty()) {
437 LOGD("no need backGround app color Switch");
438 return true;
439 }
440
441 AppExecFwk::ConfigurationPolicy policy;
442 policy.maxCountPerBatch = BackGroundAppColorSwitchSettings::GetInstance().GetTaskQuantity();
443 policy.intervalTime = BackGroundAppColorSwitchSettings::GetInstance().GetDurationMillisecond();
444 LOGI("BackGroundAppColorSwitch settings maxCountPerBatch :%{public}d intervalTime :%{public}d.",
445 BackGroundAppColorSwitchSettings::GetInstance().GetTaskQuantity(),
446 BackGroundAppColorSwitchSettings::GetInstance().GetDurationMillisecond());
447 auto result = appManagerInstance->UpdateConfigurationForBackgroundApp(backgroundAppInfoVe, policy, userId);
448 if (!result) {
449 LOGE("UpdateConfigurationForBackgroundApp fail result :%{public}d.", result);
450 return false;
451 }
452 return true;
453 }
454
UpdateConfiguration(const AppExecFwk::Configuration & configuration,const int32_t userId)455 bool UiAppearanceAbility::UpdateConfiguration(const AppExecFwk::Configuration& configuration, const int32_t userId)
456 {
457 auto appManagerInstance = GetAppManagerInstance();
458 if (appManagerInstance == nullptr) {
459 LOGE("Get app manager proxy failed.");
460 return false;
461 }
462
463 LOGI("update Configuration start,userId:%{public}d config = %{public}s.", userId, configuration.GetName().c_str());
464 auto errcode = appManagerInstance->UpdateConfiguration(configuration, userId);
465 if (errcode != 0) {
466 AppExecFwk::Configuration config;
467 auto retVal = appManagerInstance->GetConfiguration(config);
468 if (retVal != 0) {
469 LOGE("get configuration failed, update error, error is %{public}d.", retVal);
470 return false;
471 }
472 std::vector<std::string> diffVe;
473 config.CompareDifferent(diffVe, configuration);
474
475 if (!diffVe.empty()) {
476 LOGE("update configuration failed, errcode = %{public}d.", errcode);
477 return false;
478 } else {
479 LOGW("uiappearance is different against configuration. Forced to use the configuration, error is "
480 "%{public}d.",
481 errcode);
482 }
483 } else if (!configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE).empty()) {
484 BackGroundAppColorSwitch(appManagerInstance, userId);
485 }
486 return true;
487 }
488
OnSetDarkMode(const int32_t userId,DarkMode mode)489 int32_t UiAppearanceAbility::OnSetDarkMode(const int32_t userId, DarkMode mode)
490 {
491 LOGI("setDarkMode, userId:%{public}d, mode: %{public}d", userId, mode);
492 bool ret = false;
493 std::string paramValue;
494 AppExecFwk::Configuration config;
495 switch (mode) {
496 case ALWAYS_LIGHT: {
497 ret = config.AddItem(
498 AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE, AppExecFwk::ConfigurationInner::COLOR_MODE_LIGHT);
499 paramValue.assign(LIGHT);
500 break;
501 }
502 case ALWAYS_DARK: {
503 ret = config.AddItem(
504 AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE, AppExecFwk::ConfigurationInner::COLOR_MODE_DARK);
505 paramValue.assign(DARK);
506 break;
507 }
508 default:
509 break;
510 }
511 if (!ret) {
512 LOGE("AddItem failed, mode = %{public}d", mode);
513 return INVALID_ARG;
514 }
515
516 if (!UpdateConfiguration(config, userId)) {
517 return SYS_ERR;
518 }
519
520 DarkModeManager::GetInstance().DoSwitchTemporaryColorMode(userId, mode == ALWAYS_DARK ? true : false);
521
522 {
523 std::lock_guard<std::mutex> guard(usersParamMutex_);
524 usersParam_[userId].darkMode = mode;
525 }
526
527 SetParameterWrap(PERSIST_DARKMODE_KEY, paramValue);
528
529 // persist to file: etc/para/ui_appearance.para
530 auto isSetPara = SetParameterWrap(DarkModeParamAssignUser(userId), paramValue);
531 if (!isSetPara) {
532 LOGE("set parameter failed");
533 return SYS_ERR;
534 }
535 DarkModeManager::GetInstance().NotifyDarkModeUpdate(userId, mode == ALWAYS_DARK);
536 return SUCCEEDED;
537 }
538
SetDarkMode(int32_t mode,int32_t & funcResult)539 ErrCode UiAppearanceAbility::SetDarkMode(int32_t mode, int32_t& funcResult)
540 {
541 // Verify permissions
542 DarkMode darkMode = static_cast<DarkMode>(mode);
543 auto isCallingPerm = VerifyAccessToken(PERMISSION_UPDATE_CONFIGURATION);
544 if (!isCallingPerm) {
545 LOGE("permission verification failed");
546 funcResult = PERMISSION_ERR;
547 return funcResult;
548 }
549
550 auto userId = GetCallingUserId();
551 DarkMode currentDarkMode = DarkMode::ALWAYS_LIGHT;
552 {
553 std::lock_guard<std::mutex> guard(usersParamMutex_);
554 auto it = usersParam_.find(userId);
555 if (it != usersParam_.end()) {
556 currentDarkMode = it->second.darkMode;
557 }
558 }
559 if (darkMode != currentDarkMode) {
560 funcResult = OnSetDarkMode(userId, darkMode);
561 return funcResult;
562 } else {
563 LOGW("current color mode is %{public}d, no need to change", darkMode);
564 funcResult = SYS_ERR;
565 return funcResult;
566 }
567 }
568
InitGetDarkMode(const int32_t userId)569 DarkMode UiAppearanceAbility::InitGetDarkMode(const int32_t userId)
570 {
571 std::string valueGet = LIGHT;
572
573 // LIGHT is the default.
574 auto res = GetParameterWrap(DarkModeParamAssignUser(userId), valueGet);
575 if (!res) {
576 return ALWAYS_LIGHT;
577 }
578 if (valueGet == DARK) {
579 LOGI("current color mode is dark.");
580 return ALWAYS_DARK;
581 } else if (valueGet == LIGHT) {
582 LOGI("current color mode is light.");
583 return ALWAYS_LIGHT;
584 }
585 return ALWAYS_LIGHT;
586 }
587
GetDarkMode(int32_t & funcResult)588 ErrCode UiAppearanceAbility::GetDarkMode(int32_t& funcResult)
589 {
590 {
591 std::lock_guard<std::mutex> guard(usersParamMutex_);
592 auto it = usersParam_.find(GetCallingUserId());
593 if (it != usersParam_.end()) {
594 funcResult = it->second.darkMode;
595 return SUCCEEDED;
596 }
597 }
598
599 funcResult = DarkMode::ALWAYS_LIGHT;
600 return SUCCEEDED;
601 }
602
OnSetFontScale(const int32_t userId,const std::string & fontScale)603 int32_t UiAppearanceAbility::OnSetFontScale(const int32_t userId, const std::string& fontScale)
604 {
605 bool ret = false;
606 AppExecFwk::Configuration config;
607 ret = config.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_FONT_SIZE_SCALE, fontScale);
608 if (!ret) {
609 LOGE("AddItem failed, fontScale = %{public}s", fontScale.c_str());
610 return INVALID_ARG;
611 }
612 if (!UpdateConfiguration(config, userId)) {
613 return SYS_ERR;
614 }
615
616 {
617 std::lock_guard<std::mutex> guard(usersParamMutex_);
618 usersParam_[userId].fontScale = fontScale;
619 }
620
621 SetParameterWrap(FONT_SCAL_FOR_USER0, fontScale);
622 // persist to file: etc/para/ui_appearance.para
623 auto isSetPara = SetParameterWrap(FontScaleParamAssignUser(userId), fontScale);
624 if (!isSetPara) {
625 LOGE("set parameter failed");
626 return SYS_ERR;
627 }
628 return SUCCEEDED;
629 }
630
SetFontScale(const std::string & fontScale,int32_t & funcResult)631 ErrCode UiAppearanceAbility::SetFontScale(const std::string& fontScale, int32_t& funcResult)
632 {
633 // Verify permissions
634 auto isCallingPerm = VerifyAccessToken(PERMISSION_UPDATE_CONFIGURATION);
635 if (!isCallingPerm) {
636 LOGE("permission verification failed");
637 funcResult = PERMISSION_ERR;
638 return funcResult;
639 }
640 if (!fontScale.empty()) {
641 funcResult = OnSetFontScale(GetCallingUserId(), fontScale);
642 return funcResult;
643 } else {
644 LOGE("current fontScale is empty!");
645 }
646 funcResult = SYS_ERR;
647 return funcResult;
648 }
649
GetFontScale(std::string & fontScale,int32_t & funcResult)650 ErrCode UiAppearanceAbility::GetFontScale(std::string& fontScale, int32_t& funcResult)
651 {
652 {
653 std::lock_guard<std::mutex> guard(usersParamMutex_);
654 auto it = usersParam_.find(GetCallingUserId());
655 if (it != usersParam_.end()) {
656 fontScale = it->second.fontScale;
657 } else {
658 fontScale = BASE_SCALE;
659 }
660 }
661 LOGD("get font scale :%{public}s", fontScale.c_str());
662 funcResult = SUCCEEDED;
663 return funcResult;
664 }
665
OnSetFontWeightScale(const int32_t userId,const std::string & fontWeightScale)666 int32_t UiAppearanceAbility::OnSetFontWeightScale(const int32_t userId, const std::string& fontWeightScale)
667 {
668 bool ret = false;
669 AppExecFwk::Configuration config;
670 ret = config.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_FONT_WEIGHT_SCALE, fontWeightScale);
671 if (!ret) {
672 LOGE("AddItem failed, fontWeightScale = %{public}s", fontWeightScale.c_str());
673 return INVALID_ARG;
674 }
675
676 if (!UpdateConfiguration(config, userId)) {
677 return SYS_ERR;
678 }
679
680 {
681 std::lock_guard<std::mutex> guard(usersParamMutex_);
682 usersParam_[userId].fontWeightScale = fontWeightScale;
683 }
684
685 SetParameterWrap(FONT_Weight_SCAL_FOR_USER0, fontWeightScale);
686
687 // persist to file: etc/para/ui_appearance.para
688 auto isSetPara = SetParameterWrap(FontWeightScaleParamAssignUser(userId), fontWeightScale);
689 if (!isSetPara) {
690 LOGE("set parameter failed");
691 return SYS_ERR;
692 }
693 return SUCCEEDED;
694 }
695
SetFontWeightScale(const std::string & fontWeightScale,int32_t & funcResult)696 ErrCode UiAppearanceAbility::SetFontWeightScale(const std::string& fontWeightScale, int32_t& funcResult)
697 {
698 // Verify permissions
699 auto isCallingPerm = VerifyAccessToken(PERMISSION_UPDATE_CONFIGURATION);
700 if (!isCallingPerm) {
701 LOGE("permission verification failed");
702 funcResult = PERMISSION_ERR;
703 return funcResult;
704 }
705 if (!fontWeightScale.empty()) {
706 funcResult = OnSetFontWeightScale(GetCallingUserId(), fontWeightScale);
707 return funcResult;
708 } else {
709 LOGE("current fontWeightScale is empty!");
710 }
711 funcResult = SYS_ERR;
712 return funcResult;
713 }
714
GetFontWeightScale(std::string & fontWeightScale,int32_t & funcResult)715 ErrCode UiAppearanceAbility::GetFontWeightScale(std::string& fontWeightScale, int32_t& funcResult)
716 {
717 {
718 std::lock_guard<std::mutex> guard(usersParamMutex_);
719 auto it = usersParam_.find(GetCallingUserId());
720 if (it != usersParam_.end()) {
721 fontWeightScale = it->second.fontWeightScale;
722 } else {
723 fontWeightScale = BASE_SCALE;
724 }
725 }
726
727 LOGD("get font weight scale :%{public}s", fontWeightScale.c_str());
728 funcResult = SUCCEEDED;
729 return funcResult;
730 }
731
UpdateSmartGestureModeCallback(bool isAutoMode,int32_t userId)732 void UiAppearanceAbility::UpdateSmartGestureModeCallback(bool isAutoMode, int32_t userId)
733 {
734 bool ret = false;
735 AppExecFwk::Configuration config;
736 if (isAutoMode) {
737 ret = config.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_SMART_GESTURE_SWITCH,
738 AppExecFwk::ConfigurationInner::SMART_GESTURE_AUTO);
739 } else {
740 ret = config.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_SMART_GESTURE_SWITCH,
741 AppExecFwk::ConfigurationInner::SMART_GESTURE_DISABLE);
742 }
743 if (!ret) {
744 LOGE("AddItem failed, isAutoMode: %{public}d, userId: %{public}d", isAutoMode, userId);
745 return;
746 }
747
748 UpdateConfiguration(config, userId);
749 }
750
UpdateDarkModeCallback(const bool isDarkMode,const int32_t userId)751 void UiAppearanceAbility::UpdateDarkModeCallback(const bool isDarkMode, const int32_t userId)
752 {
753 bool ret = false;
754 std::string paramValue;
755 AppExecFwk::Configuration config;
756 if (isDarkMode) {
757 ret = config.AddItem(
758 AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE, AppExecFwk::ConfigurationInner::COLOR_MODE_DARK);
759 paramValue.assign(DARK);
760 } else {
761 ret = config.AddItem(
762 AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE, AppExecFwk::ConfigurationInner::COLOR_MODE_LIGHT);
763 paramValue.assign(LIGHT);
764 }
765 if (!ret) {
766 LOGE("AddItem failed, isDarkMode: %{public}d, userId: %{public}d", isDarkMode, userId);
767 return;
768 }
769
770 if (!UpdateConfiguration(config, userId)) {
771 return;
772 }
773
774 {
775 std::lock_guard<std::mutex> guard(usersParamMutex_);
776 usersParam_[userId].darkMode = isDarkMode ? ALWAYS_DARK : ALWAYS_LIGHT;
777 }
778
779 SetParameterWrap(PERSIST_DARKMODE_KEY, paramValue);
780 if (!SetParameterWrap(DarkModeParamAssignUser(userId), paramValue)) {
781 LOGE("set parameter failed");
782 }
783 }
784 } // namespace ArkUi::UiAppearance
785 } // namespace OHOS
786