1 /*
2 * Copyright (c) 2023-2024 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_tag_wrapper.h"
20 #include "hitrace_meter.h"
21 #ifdef SUPPORT_GRAPHICS
22 #include "window.h"
23 #endif
24
25 namespace OHOS {
26 namespace AbilityRuntime {
27 using namespace AppExecFwk;
28
UpdateGlobalConfig(const Configuration & configuration,std::shared_ptr<ResourceManager> resourceManager)29 void ConfigurationUtils::UpdateGlobalConfig(const Configuration &configuration,
30 std::shared_ptr<ResourceManager> resourceManager)
31 {
32 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
33 TAG_LOGD(AAFwkTag::ABILITY, "enter");
34 if (resourceManager == nullptr) {
35 TAG_LOGE(AAFwkTag::ABILITY, "null resourceManager");
36 return;
37 }
38
39 ResourceConfigHelper resourceConfig;
40 GetGlobalConfig(configuration, resourceConfig);
41 resourceConfig.UpdateResConfig(configuration, resourceManager);
42 }
43
UpdateGlobalConfig(const Configuration & configuration,std::shared_ptr<Configuration> targetConfiguration,std::shared_ptr<ResourceManager> resourceManager)44 void ConfigurationUtils::UpdateGlobalConfig(const Configuration &configuration,
45 std::shared_ptr<Configuration> targetConfiguration, std::shared_ptr<ResourceManager> resourceManager)
46 {
47 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
48 if (targetConfiguration == nullptr || resourceManager == nullptr) {
49 TAG_LOGE(AAFwkTag::ABILITY, "Input invalid");
50 return;
51 }
52 std::vector<std::string> changeKeyV;
53 targetConfiguration->CompareDifferent(changeKeyV, configuration);
54 if (changeKeyV.empty()) {
55 TAG_LOGD(AAFwkTag::ABILITY, "There's no changed config");
56 return;
57 }
58 targetConfiguration->Merge(changeKeyV, configuration);
59 ResourceConfigHelper resourceConfig;
60 GetGlobalConfig(configuration, resourceConfig);
61 resourceConfig.UpdateResConfig(configuration, resourceManager);
62 }
63
UpdateGlobalConfig(const Configuration & configuration,std::shared_ptr<Configuration> contextConfig,std::shared_ptr<Configuration> abilityConfig,std::shared_ptr<ResourceManager> resourceManager)64 Configuration ConfigurationUtils::UpdateGlobalConfig(const Configuration &configuration,
65 std::shared_ptr<Configuration> contextConfig, std::shared_ptr<Configuration> abilityConfig,
66 std::shared_ptr<ResourceManager> resourceManager)
67 {
68 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
69 if (contextConfig == nullptr || resourceManager == nullptr) {
70 TAG_LOGE(AAFwkTag::ABILITY, "Input invalid");
71 return Configuration();
72 }
73 std::vector<std::string> changeKeyV;
74 contextConfig->CompareDifferent(changeKeyV, configuration);
75 if (!changeKeyV.empty()) {
76 TAG_LOGD(AAFwkTag::ABILITY, "There's changed config");
77 contextConfig->Merge(changeKeyV, configuration);
78 }
79
80 auto newConfig = Configuration(configuration);
81 if (abilityConfig != nullptr) {
82 newConfig.FilterDuplicates(*abilityConfig);
83 }
84 TAG_LOGI(AAFwkTag::UIABILITY, "UpdateGlobalConfig newConfig: %{public}s", newConfig.GetName().c_str());
85 ResourceConfigHelper resourceConfig;
86 GetGlobalConfig(newConfig, resourceConfig);
87 resourceConfig.UpdateResConfig(newConfig, resourceManager);
88 return newConfig;
89 }
90
UpdateAbilityConfig(const Configuration & configuration,std::shared_ptr<ResourceManager> resourceManager)91 void ConfigurationUtils::UpdateAbilityConfig(const Configuration &configuration,
92 std::shared_ptr<ResourceManager> resourceManager)
93 {
94 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
95 if (resourceManager == nullptr) {
96 TAG_LOGE(AAFwkTag::ABILITY, "Input invalid");
97 return;
98 }
99 ResourceConfigHelper resourceConfig;
100 GetGlobalConfig(configuration, resourceConfig);
101 resourceConfig.SetISAbilityColor(true);
102 resourceConfig.UpdateResConfig(configuration, resourceManager);
103 }
104
GetGlobalConfig(const Configuration & configuration,OHOS::AbilityRuntime::ResourceConfigHelper & resourceConfig)105 void ConfigurationUtils::GetGlobalConfig(const Configuration &configuration,
106 OHOS::AbilityRuntime::ResourceConfigHelper &resourceConfig)
107 {
108 resourceConfig.SetLanguage(configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE));
109 resourceConfig.SetLocale(configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_LOCALE));
110 resourceConfig.SetColormode(configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE));
111 resourceConfig.SetHasPointerDevice(configuration.GetItem(AAFwk::GlobalConfigurationKey::INPUT_POINTER_DEVICE));
112 resourceConfig.SetMcc(configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_MCC));
113 resourceConfig.SetMnc(configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_MNC));
114 resourceConfig.SetThemeId(configuration.GetItem(AAFwk::GlobalConfigurationKey::THEME_ID));
115 resourceConfig.SetThemeIcon(configuration.GetItem(AAFwk::GlobalConfigurationKey::THEME_ICON));
116 }
117
118 #ifdef SUPPORT_GRAPHICS
InitDisplayConfig(Rosen::DisplayId displayId,std::shared_ptr<Configuration> configuration,std::shared_ptr<ResourceManager> resourceManager)119 void ConfigurationUtils::InitDisplayConfig(Rosen::DisplayId displayId, std::shared_ptr<Configuration> configuration,
120 std::shared_ptr<ResourceManager> resourceManager)
121 {
122 TAG_LOGD(AAFwkTag::ABILITY, "init display config");
123 if (configuration == nullptr || resourceManager == nullptr) {
124 TAG_LOGE(AAFwkTag::ABILITY, "input invalid");
125 return;
126 }
127
128 float density;
129 std::string direction;
130 if (!GetDisplayConfig(displayId, density, direction)) {
131 return;
132 }
133
134 configuration->AddItem(displayId, ConfigurationInner::APPLICATION_DENSITYDPI, GetDensityStr(density));
135 configuration->AddItem(displayId, ConfigurationInner::APPLICATION_DIRECTION, direction);
136 configuration->AddItem(ConfigurationInner::APPLICATION_DISPLAYID, std::to_string(displayId));
137
138 UpdateDisplayResConfig(resourceManager, density, direction);
139 }
140
UpdateDisplayConfig(Rosen::DisplayId displayId,std::shared_ptr<Configuration> configuration,std::shared_ptr<ResourceManager> resourceManager,bool & configChanged)141 void ConfigurationUtils::UpdateDisplayConfig(Rosen::DisplayId displayId, std::shared_ptr<Configuration> configuration,
142 std::shared_ptr<ResourceManager> resourceManager, bool &configChanged)
143 {
144 TAG_LOGD(AAFwkTag::ABILITY, "update display config");
145 if (configuration == nullptr || resourceManager == nullptr) {
146 TAG_LOGE(AAFwkTag::ABILITY, "input invalid");
147 return;
148 }
149
150 float density;
151 std::string direction;
152 if (!GetDisplayConfig(displayId, density, direction)) {
153 return;
154 }
155
156 Configuration newConfig;
157 newConfig.AddItem(displayId, ConfigurationInner::APPLICATION_DENSITYDPI, GetDensityStr(density));
158 newConfig.AddItem(displayId, ConfigurationInner::APPLICATION_DIRECTION, direction);
159
160 std::vector<std::string> changeKeyV;
161 configuration->CompareDifferent(changeKeyV, newConfig);
162 if (changeKeyV.empty()) {
163 TAG_LOGD(AAFwkTag::ABILITY, "no changed config");
164 return;
165 }
166 configuration->Merge(changeKeyV, newConfig);
167 configChanged = true;
168
169 UpdateDisplayResConfig(resourceManager, density, direction);
170
171 auto diffConfiguration = std::make_shared<AppExecFwk::Configuration>(newConfig);
172 TAG_LOGI(AAFwkTag::ABILITY, "update display config %{public}s for all windows",
173 diffConfiguration->GetName().c_str());
174 Rosen::Window::UpdateConfigurationForAll(diffConfiguration);
175 }
176
InitDisplayConfig(std::shared_ptr<Configuration> configuration,std::shared_ptr<ResourceManager> resourceManager,Rosen::DisplayId displayId,float density,int32_t orientation)177 void ConfigurationUtils::InitDisplayConfig(std::shared_ptr<Configuration> configuration,
178 std::shared_ptr<ResourceManager> resourceManager, Rosen::DisplayId displayId, float density, int32_t orientation)
179 {
180 TAG_LOGD(AAFwkTag::ABILITY, "Init display config");
181 if (configuration == nullptr || resourceManager == nullptr) {
182 TAG_LOGE(AAFwkTag::ABILITY, "Input invalid");
183 return;
184 }
185 auto direction = GetDirectionStr(orientation);
186 configuration->AddItem(displayId, ConfigurationInner::APPLICATION_DENSITYDPI, GetDensityStr(density));
187 configuration->AddItem(displayId, ConfigurationInner::APPLICATION_DIRECTION, direction);
188 configuration->AddItem(ConfigurationInner::APPLICATION_DISPLAYID, std::to_string(displayId));
189 UpdateDisplayResConfig(resourceManager, density, direction);
190 }
191
UpdateDisplayConfig(std::shared_ptr<Configuration> configuration,std::shared_ptr<ResourceManager> resourceManager,Rosen::DisplayId displayId,float density,Rosen::DisplayOrientation orientation)192 bool ConfigurationUtils::UpdateDisplayConfig(std::shared_ptr<Configuration> configuration,
193 std::shared_ptr<ResourceManager> resourceManager, Rosen::DisplayId displayId, float density,
194 Rosen::DisplayOrientation orientation)
195 {
196 TAG_LOGD(AAFwkTag::ABILITY, "Update display config");
197 if (configuration == nullptr || resourceManager == nullptr) {
198 TAG_LOGE(AAFwkTag::ABILITY, "Input invalid");
199 return false;
200 }
201 auto direction = GetDirectionStr(static_cast<int32_t>(orientation));
202 Configuration newConfig;
203 newConfig.AddItem(displayId, ConfigurationInner::APPLICATION_DENSITYDPI, GetDensityStr(density));
204 newConfig.AddItem(displayId, ConfigurationInner::APPLICATION_DIRECTION, direction);
205
206 std::vector<std::string> changeKeyV;
207 configuration->CompareDifferent(changeKeyV, newConfig);
208 if (changeKeyV.empty()) {
209 TAG_LOGD(AAFwkTag::ABILITY, "There's no changed config");
210 return false;
211 }
212 configuration->Merge(changeKeyV, newConfig);
213 UpdateDisplayResConfig(resourceManager, density, direction);
214 return true;
215 }
216
GetDisplayConfig(Rosen::DisplayId displayId,float & density,std::string & directionStr)217 bool ConfigurationUtils::GetDisplayConfig(Rosen::DisplayId displayId, float &density,
218 std::string &directionStr)
219 {
220 TAG_LOGD(AAFwkTag::ABILITY, "get display by id %{public}" PRIu64"", displayId);
221 auto display = Rosen::DisplayManager::GetInstance().GetDisplayById(displayId);
222 if (display == nullptr) {
223 TAG_LOGE(AAFwkTag::ABILITY, "display %{public}" PRIu64" failed", displayId);
224 return false;
225 }
226
227 density = display->GetVirtualPixelRatio();
228 int32_t width = display->GetWidth();
229 int32_t height = display->GetHeight();
230 directionStr = GetDirectionStr(height, width);
231 TAG_LOGD(AAFwkTag::ABILITY, "displayId: %{public}" PRIu64", density: %{public}f, direction: %{public}s",
232 displayId, density, directionStr.c_str());
233 return true;
234 }
235
UpdateDisplayResConfig(std::shared_ptr<ResourceManager> resourceManager,float & density,std::string & direction)236 void ConfigurationUtils::UpdateDisplayResConfig(std::shared_ptr<ResourceManager> resourceManager,
237 float &density, std::string &direction)
238 {
239 // resourceManager has checked in caller function.
240 TAG_LOGD(AAFwkTag::ABILITY, "update resConfig, density: %{public}f, direction: %{public}s",
241 density, direction.c_str());
242 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
243 if (resConfig == nullptr) {
244 TAG_LOGE(AAFwkTag::ABILITY, "null resConfig");
245 return;
246 }
247
248 resourceManager->GetResConfig(*resConfig);
249 resConfig->SetScreenDensity(density);
250 resConfig->SetDirection(ConvertDirection(direction));
251 resourceManager->UpdateResConfig(*resConfig);
252 TAG_LOGD(AAFwkTag::ABILITY, "update resConfig finished, density: %{public}f, direction: %{public}d",
253 resConfig->GetScreenDensity(), resConfig->GetDirection());
254 }
255 #endif
256 } // namespace AbilityRuntime
257 } // namespace OHOS
258