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