• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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