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, "invalid Resource manager");
36 return;
37 }
38
39 ResourceConfigHelper resourceConfig;
40 GetGlobalConfig(configuration, resourceConfig);
41 resourceConfig.UpdateResConfig(configuration, resourceManager);
42 }
43
GetGlobalConfig(const Configuration & configuration,OHOS::AbilityRuntime::ResourceConfigHelper & resourceConfig)44 void ConfigurationUtils::GetGlobalConfig(const Configuration &configuration,
45 OHOS::AbilityRuntime::ResourceConfigHelper &resourceConfig)
46 {
47 resourceConfig.SetLanguage(configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE));
48 resourceConfig.SetColormode(configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE));
49 resourceConfig.SetHasPointerDevice(configuration.GetItem(AAFwk::GlobalConfigurationKey::INPUT_POINTER_DEVICE));
50 resourceConfig.SetMcc(configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_MCC));
51 resourceConfig.SetMnc(configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_MNC));
52 resourceConfig.SetThemeId(configuration.GetItem(AAFwk::GlobalConfigurationKey::THEME_ID));
53 }
54
55 #ifdef SUPPORT_GRAPHICS
InitDisplayConfig(Rosen::DisplayId displayId,std::shared_ptr<Configuration> configuration,std::shared_ptr<ResourceManager> resourceManager)56 void ConfigurationUtils::InitDisplayConfig(Rosen::DisplayId displayId, std::shared_ptr<Configuration> configuration,
57 std::shared_ptr<ResourceManager> resourceManager)
58 {
59 TAG_LOGD(AAFwkTag::ABILITY, "init display config");
60 if (configuration == nullptr || resourceManager == nullptr) {
61 TAG_LOGE(AAFwkTag::ABILITY, "input invalid");
62 return;
63 }
64
65 float density;
66 std::string direction;
67 if (!GetDisplayConfig(displayId, density, direction)) {
68 return;
69 }
70
71 configuration->AddItem(displayId, ConfigurationInner::APPLICATION_DENSITYDPI, GetDensityStr(density));
72 configuration->AddItem(displayId, ConfigurationInner::APPLICATION_DIRECTION, direction);
73 configuration->AddItem(ConfigurationInner::APPLICATION_DISPLAYID, std::to_string(displayId));
74
75 UpdateDisplayResConfig(resourceManager, density, direction);
76 }
77
UpdateDisplayConfig(Rosen::DisplayId displayId,std::shared_ptr<Configuration> configuration,std::shared_ptr<ResourceManager> resourceManager,bool & configChanged)78 void ConfigurationUtils::UpdateDisplayConfig(Rosen::DisplayId displayId, std::shared_ptr<Configuration> configuration,
79 std::shared_ptr<ResourceManager> resourceManager, bool &configChanged)
80 {
81 TAG_LOGD(AAFwkTag::ABILITY, "update display config");
82 if (configuration == nullptr || resourceManager == nullptr) {
83 TAG_LOGE(AAFwkTag::ABILITY, "input invalid");
84 return;
85 }
86
87 float density;
88 std::string direction;
89 if (!GetDisplayConfig(displayId, density, direction)) {
90 return;
91 }
92
93 Configuration newConfig;
94 newConfig.AddItem(displayId, ConfigurationInner::APPLICATION_DENSITYDPI, GetDensityStr(density));
95 newConfig.AddItem(displayId, ConfigurationInner::APPLICATION_DIRECTION, direction);
96
97 std::vector<std::string> changeKeyV;
98 configuration->CompareDifferent(changeKeyV, newConfig);
99 if (changeKeyV.empty()) {
100 TAG_LOGD(AAFwkTag::ABILITY, "no changed config");
101 return;
102 }
103 configuration->Merge(changeKeyV, newConfig);
104 configChanged = true;
105
106 UpdateDisplayResConfig(resourceManager, density, direction);
107
108 auto diffConfiguration = std::make_shared<AppExecFwk::Configuration>(newConfig);
109 TAG_LOGI(AAFwkTag::ABILITY, "update display config %{public}s for all windows",
110 diffConfiguration->GetName().c_str());
111 Rosen::Window::UpdateConfigurationForAll(diffConfiguration);
112 }
113
GetDisplayConfig(Rosen::DisplayId displayId,float & density,std::string & directionStr)114 bool ConfigurationUtils::GetDisplayConfig(Rosen::DisplayId displayId, float &density,
115 std::string &directionStr)
116 {
117 TAG_LOGD(AAFwkTag::ABILITY, "get display by id %{public}" PRIu64"", displayId);
118 auto display = Rosen::DisplayManager::GetInstance().GetDisplayById(displayId);
119 if (display == nullptr) {
120 TAG_LOGE(AAFwkTag::ABILITY, "display %{public}" PRIu64" failed", displayId);
121 return false;
122 }
123
124 density = display->GetVirtualPixelRatio();
125 int32_t width = display->GetWidth();
126 int32_t height = display->GetHeight();
127 directionStr = GetDirectionStr(height, width);
128 TAG_LOGD(AAFwkTag::ABILITY, "displayId: %{public}" PRIu64", density: %{public}f, direction: %{public}s",
129 displayId, density, directionStr.c_str());
130 return true;
131 }
132
UpdateDisplayResConfig(std::shared_ptr<ResourceManager> resourceManager,float & density,std::string & direction)133 void ConfigurationUtils::UpdateDisplayResConfig(std::shared_ptr<ResourceManager> resourceManager,
134 float &density, std::string &direction)
135 {
136 // resourceManager has checked in caller function.
137 TAG_LOGD(AAFwkTag::ABILITY, "update resConfig, density: %{public}f, direction: %{public}s",
138 density, direction.c_str());
139 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
140 if (resConfig == nullptr) {
141 TAG_LOGE(AAFwkTag::ABILITY, "create resConfig failed");
142 return;
143 }
144
145 resourceManager->GetResConfig(*resConfig);
146 resConfig->SetScreenDensity(density);
147 resConfig->SetDirection(ConvertDirection(direction));
148 resourceManager->UpdateResConfig(*resConfig);
149 TAG_LOGD(AAFwkTag::ABILITY, "update resConfig finished, density: %{public}f, direction: %{public}d",
150 resConfig->GetScreenDensity(), resConfig->GetDirection());
151 }
152 #endif
153 } // namespace AbilityRuntime
154 } // namespace OHOS
155