1 /*
2 * Copyright (c) 2023 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 "configuration_utils.h"
17
18 #include "configuration_convertor.h"
19 #include "hilog_wrapper.h"
20 #ifdef SUPPORT_GRAPHICS
21 #include "window.h"
22 #endif
23
24 namespace OHOS {
25 namespace AbilityRuntime {
26 using namespace AppExecFwk;
27
UpdateGlobalConfig(const Configuration & configuration,std::shared_ptr<ResourceManager> resourceManager)28 void ConfigurationUtils::UpdateGlobalConfig(const Configuration &configuration,
29 std::shared_ptr<ResourceManager> resourceManager)
30 {
31 HILOG_DEBUG("Enter");
32 if (resourceManager == nullptr) {
33 HILOG_ERROR("Resource manager is invalid.");
34 return;
35 }
36
37 std::string language;
38 std::string colormode;
39 std::string hasPointerDevice;
40 GetGlobalConfig(configuration, language, colormode, hasPointerDevice);
41 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
42 if (resConfig == nullptr) {
43 HILOG_ERROR("Create resource config failed.");
44 return;
45 }
46 resourceManager->GetResConfig(*resConfig);
47
48 #ifdef SUPPORT_GRAPHICS
49 if (!language.empty()) {
50 UErrorCode status = U_ZERO_ERROR;
51 icu::Locale locale = icu::Locale::forLanguageTag(language, status);
52 HILOG_DEBUG("get Locale::forLanguageTag return[%{public}d].", static_cast<int>(status));
53 if (status == U_ZERO_ERROR) {
54 resConfig->SetLocaleInfo(locale);
55 }
56
57 const icu::Locale *localeInfo = resConfig->GetLocaleInfo();
58 if (localeInfo != nullptr) {
59 HILOG_DEBUG("Update config, language: %{public}s, script: %{public}s, region: %{public}s",
60 localeInfo->getLanguage(), localeInfo->getScript(), localeInfo->getCountry());
61 }
62 }
63 #endif
64
65 if (!colormode.empty()) {
66 resConfig->SetColorMode(AppExecFwk::ConvertColorMode(colormode));
67 HILOG_DEBUG("Update config, colorMode: %{public}d", resConfig->GetColorMode());
68 }
69
70 if (!hasPointerDevice.empty()) {
71 resConfig->SetInputDevice(AppExecFwk::ConvertHasPointerDevice(hasPointerDevice));
72 HILOG_DEBUG("Update config, hasPointerDevice: %{public}d", resConfig->GetInputDevice());
73 }
74
75 Global::Resource::RState ret = resourceManager->UpdateResConfig(*resConfig);
76 if (ret != Global::Resource::RState::SUCCESS) {
77 HILOG_ERROR("Update resource config failed with %{public}d.", static_cast<int>(ret));
78 return;
79 }
80
81 HILOG_DEBUG("Update resource config succeed.");
82 }
83
GetGlobalConfig(const Configuration & configuration,std::string & language,std::string & colormode,std::string & hasPointerDevice)84 void ConfigurationUtils::GetGlobalConfig(const Configuration &configuration,
85 std::string &language, std::string &colormode, std::string &hasPointerDevice)
86 {
87 language = configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE);
88 colormode = configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
89 hasPointerDevice = configuration.GetItem(AAFwk::GlobalConfigurationKey::INPUT_POINTER_DEVICE);
90 }
91
92 #ifdef SUPPORT_GRAPHICS
InitDisplayConfig(Rosen::DisplayId displayId,std::shared_ptr<Configuration> configuration,std::shared_ptr<ResourceManager> resourceManager)93 void ConfigurationUtils::InitDisplayConfig(Rosen::DisplayId displayId, std::shared_ptr<Configuration> configuration,
94 std::shared_ptr<ResourceManager> resourceManager)
95 {
96 HILOG_DEBUG("Init display config.");
97 if (configuration == nullptr || resourceManager == nullptr) {
98 HILOG_ERROR("Input invalid.");
99 return;
100 }
101
102 float density;
103 std::string direction;
104 if (!GetDisplayConfig(displayId, density, direction)) {
105 return;
106 }
107
108 configuration->AddItem(displayId, ConfigurationInner::APPLICATION_DENSITYDPI, GetDensityStr(density));
109 configuration->AddItem(displayId, ConfigurationInner::APPLICATION_DIRECTION, direction);
110 configuration->AddItem(ConfigurationInner::APPLICATION_DISPLAYID, std::to_string(displayId));
111
112 UpdateDisplayResConfig(resourceManager, density, direction);
113 }
114
UpdateDisplayConfig(Rosen::DisplayId displayId,std::shared_ptr<Configuration> configuration,std::shared_ptr<ResourceManager> resourceManager,bool & configChanged)115 void ConfigurationUtils::UpdateDisplayConfig(Rosen::DisplayId displayId, std::shared_ptr<Configuration> configuration,
116 std::shared_ptr<ResourceManager> resourceManager, bool &configChanged)
117 {
118 HILOG_DEBUG("Update display config.");
119 if (configuration == nullptr || resourceManager == nullptr) {
120 HILOG_ERROR("Input invalid.");
121 return;
122 }
123
124 float density;
125 std::string direction;
126 if (!GetDisplayConfig(displayId, density, direction)) {
127 return;
128 }
129
130 Configuration newConfig;
131 newConfig.AddItem(displayId, ConfigurationInner::APPLICATION_DENSITYDPI, GetDensityStr(density));
132 newConfig.AddItem(displayId, ConfigurationInner::APPLICATION_DIRECTION, direction);
133
134 std::vector<std::string> changeKeyV;
135 configuration->CompareDifferent(changeKeyV, newConfig);
136 if (changeKeyV.empty()) {
137 HILOG_INFO("There's no changed config, return.");
138 return;
139 }
140 configuration->Merge(changeKeyV, newConfig);
141 configChanged = true;
142
143 UpdateDisplayResConfig(resourceManager, density, direction);
144
145 auto diffConfiguration = std::make_shared<AppExecFwk::Configuration>(newConfig);
146 HILOG_INFO("Update display config %{public}s for all windows.", diffConfiguration->GetName().c_str());
147 Rosen::Window::UpdateConfigurationForAll(diffConfiguration);
148 }
149
GetDisplayConfig(Rosen::DisplayId displayId,float & density,std::string & directionStr)150 bool ConfigurationUtils::GetDisplayConfig(Rosen::DisplayId displayId, float &density,
151 std::string &directionStr)
152 {
153 HILOG_DEBUG("Get display by id %{public}" PRIu64".", displayId);
154 auto display = Rosen::DisplayManager::GetInstance().GetDisplayById(displayId);
155 if (display == nullptr) {
156 HILOG_ERROR("Get display %{public}" PRIu64" failed.", displayId);
157 return false;
158 }
159
160 density = display->GetVirtualPixelRatio();
161 int32_t width = display->GetWidth();
162 int32_t height = display->GetHeight();
163 directionStr = GetDirectionStr(height, width);
164 HILOG_DEBUG("DisplayId: %{public}" PRIu64", density: %{public}f, direction: %{public}s.", displayId,
165 density, directionStr.c_str());
166 return true;
167 }
168
UpdateDisplayResConfig(std::shared_ptr<ResourceManager> resourceManager,float & density,std::string & direction)169 void ConfigurationUtils::UpdateDisplayResConfig(std::shared_ptr<ResourceManager> resourceManager,
170 float &density, std::string &direction)
171 {
172 // resourceManager has checked in caller function.
173 HILOG_INFO("Update resConfig, density: %{public}f, direction: %{public}s.", density, direction.c_str());
174 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
175 if (resConfig == nullptr) {
176 HILOG_ERROR("Create resConfig failed.");
177 return;
178 }
179
180 resourceManager->GetResConfig(*resConfig);
181 resConfig->SetScreenDensity(density);
182 resConfig->SetDirection(ConvertDirection(direction));
183 resourceManager->UpdateResConfig(*resConfig);
184 HILOG_INFO("Update resConfig finished, density: %{public}f, direction: %{public}d.", resConfig->GetScreenDensity(),
185 resConfig->GetDirection());
186 }
187 #endif
188 } // namespace AbilityRuntime
189 } // namespace OHOS
190