1 /*
2 * Copyright (c) 2022-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 "cj_environment_callback.h"
17
18 #include "hilog_tag_wrapper.h"
19
20 namespace OHOS {
21 namespace AbilityRuntime {
CjEnvironmentCallback()22 CjEnvironmentCallback::CjEnvironmentCallback()
23 {
24 }
25
26 int32_t CjEnvironmentCallback::serialNumber_ = 0;
27
ConvertColorMode(std::string colormode)28 int32_t ConvertColorMode(std::string colormode)
29 {
30 auto resolution = -1;
31 static const std::vector<std::pair<std::string, int32_t>> resolutions = {
32 { "dark", 0 },
33 { "light", 1 },
34 };
35 for (const auto& [tempColorMode, value] : resolutions) {
36 if (tempColorMode == colormode) {
37 resolution = value;
38 break;
39 }
40 }
41 return resolution;
42 }
43
ConvertDirection(std::string direction)44 int32_t ConvertDirection(std::string direction)
45 {
46 auto resolution = -1;
47 static const std::vector<std::pair<std::string, int32_t>> resolutions = {
48 { "vertical", 0 },
49 { "horizontal", 1 },
50 };
51 for (const auto& [tempDirection, value] : resolutions) {
52 if (tempDirection == direction) {
53 resolution = value;
54 break;
55 }
56 }
57 return resolution;
58 }
59
ConvertDensity(std::string density)60 int32_t ConvertDensity(std::string density)
61 {
62 auto resolution = 0;
63 static const std::vector<std::pair<std::string, int32_t>> resolutions = {
64 { "sdpi", 120 },
65 { "mdpi", 160 },
66 { "ldpi", 240 },
67 { "xldpi", 320 },
68 { "xxldpi", 480 },
69 { "xxxldpi", 640 },
70 };
71 for (const auto& [tempdensity, value] : resolutions) {
72 if (tempdensity == density) {
73 resolution = value;
74 break;
75 }
76 }
77 return resolution;
78 }
79
ConvertDisplayId(std::string displayId)80 int32_t ConvertDisplayId(std::string displayId)
81 {
82 if (displayId == AppExecFwk::ConfigurationInner::EMPTY_STRING) {
83 return -1;
84 }
85 return std::stoi(displayId);
86 }
87
CreateCConfiguration(const AppExecFwk::Configuration &configuration)88 CConfiguration CreateCConfiguration(const AppExecFwk::Configuration &configuration)
89 {
90 CConfiguration cfg;
91 cfg.language = CreateCStringFromString(configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE));
92 cfg.colorMode = ConvertColorMode(configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE));
93 std::string direction = configuration.GetItem(AppExecFwk::ConfigurationInner::APPLICATION_DIRECTION);
94 cfg.direction = ConvertDirection(direction);
95 std::string density = configuration.GetItem(AppExecFwk::ConfigurationInner::APPLICATION_DENSITYDPI);
96 cfg.screenDensity = ConvertDensity(density);
97 cfg.displayId = ConvertDisplayId(configuration.GetItem(AppExecFwk::ConfigurationInner::APPLICATION_DISPLAYID));
98 std::string hasPointerDevice = configuration.GetItem(AAFwk::GlobalConfigurationKey::INPUT_POINTER_DEVICE);
99 cfg.hasPointerDevice = hasPointerDevice == "true" ? true : false;
100 std::string fontSizeScale = configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_FONT_SIZE_SCALE);
101 cfg.fontSizeScale = fontSizeScale == "" ? 1.0 : std::stod(fontSizeScale);
102 std::string fontWeightScale = configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_FONT_WEIGHT_SCALE);
103 cfg.fontWeightScale = fontWeightScale == "" ? 1.0 : std::stod(fontWeightScale);
104 cfg.mcc = CreateCStringFromString(configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_MCC));
105 cfg.mnc = CreateCStringFromString(configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_MNC));
106 return cfg;
107 }
108
CallConfigurationUpdatedInner(const AppExecFwk::Configuration &config, const std::map<int32_t, std::function<void(CConfiguration)>> &callbacks)109 void CjEnvironmentCallback::CallConfigurationUpdatedInner(const AppExecFwk::Configuration &config,
110 const std::map<int32_t, std::function<void(CConfiguration)>> &callbacks)
111 {
112 TAG_LOGD(AAFwkTag::APPKIT, "methodName = onConfiguration");
113 for (auto &callback : callbacks) {
114 if (!callback.second) {
115 TAG_LOGE(AAFwkTag::APPKIT, " Invalid cjCallback");
116 return;
117 }
118 auto cfg = CreateCConfiguration(config);
119 callback.second(cfg);
120 }
121 }
122
OnConfigurationUpdated(const AppExecFwk::Configuration &config)123 void CjEnvironmentCallback::OnConfigurationUpdated(const AppExecFwk::Configuration &config)
124 {
125 std::weak_ptr<CjEnvironmentCallback> thisWeakPtr(shared_from_this());
126 std::shared_ptr<CjEnvironmentCallback> cjEnvCallback = thisWeakPtr.lock();
127 if (cjEnvCallback) {
128 cjEnvCallback->CallConfigurationUpdatedInner(config, onConfigurationUpdatedCallbacks_);
129 }
130 }
131
CallMemoryLevelInner(const int level, const std::map<int32_t, std::function<void(int32_t)>> &callbacks)132 void CjEnvironmentCallback::CallMemoryLevelInner(const int level,
133 const std::map<int32_t, std::function<void(int32_t)>> &callbacks)
134 {
135 TAG_LOGD(AAFwkTag::APPKIT, "onMemoryLevel");
136 for (auto &callback : callbacks) {
137 if (!callback.second) {
138 TAG_LOGE(AAFwkTag::APPKIT, "Invalid jsCallback");
139 return;
140 }
141 callback.second(static_cast<int32_t>(level));
142 }
143 }
144
OnMemoryLevel(const int level)145 void CjEnvironmentCallback::OnMemoryLevel(const int level)
146 {
147 std::weak_ptr<CjEnvironmentCallback> thisWeakPtr(shared_from_this());
148 std::shared_ptr<CjEnvironmentCallback> cjEnvCallback = thisWeakPtr.lock();
149 if (cjEnvCallback) {
150 cjEnvCallback->CallMemoryLevelInner(level, onMemoryLevelCallbacks_);
151 }
152 }
153
Register(std::function<void(CConfiguration)> cfgCallback, std::function<void(int32_t)> memCallback, bool isSync)154 int32_t CjEnvironmentCallback::Register(std::function<void(CConfiguration)> cfgCallback,
155 std::function<void(int32_t)> memCallback, bool isSync)
156 {
157 int32_t callbackId = serialNumber_;
158 if (serialNumber_ < INT32_MAX) {
159 serialNumber_++;
160 } else {
161 serialNumber_ = 0;
162 }
163 if (isSync) {
164 return -1;
165 } else {
166 onConfigurationUpdatedCallbacks_.emplace(callbackId, cfgCallback);
167 onMemoryLevelCallbacks_.emplace(callbackId, memCallback);
168 }
169 return callbackId;
170 }
171
UnRegister(int32_t callbackId, bool isSync)172 bool CjEnvironmentCallback::UnRegister(int32_t callbackId, bool isSync)
173 {
174 TAG_LOGD(AAFwkTag::APPKIT, "callbackId : %{public}d", callbackId);
175 if (isSync) {
176 return false;
177 }
178 auto itCfg = onConfigurationUpdatedCallbacks_.find(callbackId);
179 if (itCfg == onConfigurationUpdatedCallbacks_.end()) {
180 TAG_LOGE(AAFwkTag::APPKIT, "callbackId: %{public}d is not in callbacks_", callbackId);
181 return false;
182 }
183 TAG_LOGD(AAFwkTag::APPKIT, "callbacks_.callbackId : %{public}d", itCfg->first);
184 auto itMem = onMemoryLevelCallbacks_.find(callbackId);
185 if (itMem == onMemoryLevelCallbacks_.end()) {
186 TAG_LOGE(AAFwkTag::APPKIT, "callbackId: %{public}d is not in callbacks_", callbackId);
187 return false;
188 }
189 TAG_LOGD(AAFwkTag::APPKIT, "callbacks_.callbackId : %{public}d", itMem->first);
190 return onConfigurationUpdatedCallbacks_.erase(callbackId) == 1 && onMemoryLevelCallbacks_.erase(callbackId) == 1;
191 }
192
IsEmpty() const193 bool CjEnvironmentCallback::IsEmpty() const
194 {
195 return onConfigurationUpdatedCallbacks_.empty() && onMemoryLevelCallbacks_.empty();
196 }
197 } // namespace AbilityRuntime
198 } // namespace OHOS