1 /*
2 * Copyright (c) 2021-2022 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.h"
17
18 #include <mutex>
19 #include <nlohmann/json.hpp>
20
21 #include "ability_base_log_wrapper.h"
22 #include "string_ex.h"
23
24 namespace OHOS {
25 namespace AppExecFwk {
26 namespace {
27 constexpr int CYCLE_LIMIT = 1000;
28 }
29 using json = nlohmann::json;
Configuration()30 Configuration::Configuration()
31 {}
32
Configuration(const Configuration & other)33 Configuration::Configuration(const Configuration &other) : defaultDisplayId_(other.defaultDisplayId_)
34 {
35 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
36 configParameter_ = other.configParameter_;
37 }
38
operator =(const Configuration & other)39 Configuration& Configuration::operator=(const Configuration &other)
40 {
41 if (this == &other) {
42 return *this;
43 }
44
45 defaultDisplayId_ = other.defaultDisplayId_;
46
47 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
48 configParameter_.clear();
49 configParameter_ = other.configParameter_;
50 return *this;
51 }
52
~Configuration()53 Configuration::~Configuration()
54 {}
55
MakeTheKey(std::string & getKey,int id,const std::string & param) const56 bool Configuration::MakeTheKey(std::string &getKey, int id, const std::string ¶m) const
57 {
58 if (param.empty()) {
59 return false;
60 }
61
62 const std::vector<std::string> SystemConfigurationKeyStore {
63 OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE,
64 OHOS::AAFwk::GlobalConfigurationKey::IS_PREFERRED_LANGUAGE,
65 OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_LOCALE,
66 OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_HOUR,
67 OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE,
68 OHOS::AAFwk::GlobalConfigurationKey::INPUT_POINTER_DEVICE,
69 OHOS::AAFwk::GlobalConfigurationKey::DEVICE_TYPE,
70 OHOS::AAFwk::GlobalConfigurationKey::THEME,
71 OHOS::AAFwk::GlobalConfigurationKey::THEME_ID,
72 OHOS::AAFwk::GlobalConfigurationKey::THEME_ICON,
73 OHOS::AAFwk::GlobalConfigurationKey::COLORMODE_IS_SET_BY_SA,
74 OHOS::AAFwk::GlobalConfigurationKey::COLORMODE_IS_SET_BY_APP,
75 OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_FONT_ID,
76 OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_FONT_SIZE_SCALE,
77 OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_FONT_WEIGHT_SCALE,
78 OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_MCC,
79 OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_MNC,
80 OHOS::AppExecFwk::ConfigurationInner::APPLICATION_DIRECTION,
81 OHOS::AppExecFwk::ConfigurationInner::APPLICATION_DENSITYDPI,
82 OHOS::AppExecFwk::ConfigurationInner::APPLICATION_DISPLAYID,
83 OHOS::AppExecFwk::ConfigurationInner::APPLICATION_FONT,
84 OHOS::AAFwk::GlobalConfigurationKey::APP_FONT_SIZE_SCALE,
85 OHOS::AAFwk::GlobalConfigurationKey::APP_FONT_MAX_SCALE,
86 OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_SMART_GESTURE_SWITCH,
87 };
88 if (std::find(SystemConfigurationKeyStore.begin(), SystemConfigurationKeyStore.end(), param) ==
89 SystemConfigurationKeyStore.end()) {
90 return false;
91 }
92
93 getKey.clear();
94 getKey += std::to_string(id);
95 getKey += ConfigurationInner::CONNECTION_SYMBOL;
96 getKey += param;
97 ABILITYBASE_LOGD("key: %{public}s", getKey.c_str());
98
99 return true;
100 }
101
AddItem(int displayId,const std::string & key,const std::string & value)102 bool Configuration::AddItem(int displayId, const std::string &key, const std::string &value)
103 {
104 if (key.empty() || value.empty()) {
105 return false;
106 }
107
108 std::string getKey;
109 if (!MakeTheKey(getKey, displayId, key)) {
110 return false;
111 }
112
113 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
114 configParameter_[getKey] = value;
115 return true;
116 }
117
GetItem(int displayId,const std::string & key) const118 std::string Configuration::GetItem(int displayId, const std::string &key) const
119 {
120 if (key.empty()) {
121 return ConfigurationInner::EMPTY_STRING;
122 }
123
124 std::string getKey;
125 if (!MakeTheKey(getKey, displayId, key)) {
126 return ConfigurationInner::EMPTY_STRING;
127 }
128
129 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
130 auto iter = configParameter_.find(getKey);
131 if (iter != configParameter_.end()) {
132 return iter->second;
133 }
134
135 return ConfigurationInner::EMPTY_STRING;
136 }
137
GetItemSize() const138 int Configuration::GetItemSize() const
139 {
140 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
141 return configParameter_.size();
142 }
143
GetAllKey(std::vector<std::string> & keychain) const144 void Configuration::GetAllKey(std::vector<std::string> &keychain) const
145 {
146 keychain.clear();
147
148 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
149 for (const auto &it :configParameter_) {
150 keychain.push_back(it.first);
151 }
152 }
153
GetValue(const std::string & key) const154 std::string Configuration::GetValue(const std::string &key) const
155 {
156 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
157 auto iter = configParameter_.find(key);
158 if (iter != configParameter_.end()) {
159 return iter->second;
160 }
161
162 return ConfigurationInner::EMPTY_STRING;
163 }
164
CompareDifferent(std::vector<std::string> & diffKeyV,const Configuration & other)165 void Configuration::CompareDifferent(std::vector<std::string> &diffKeyV, const Configuration &other)
166 {
167 if (other.GetItemSize() == 0) {
168 return;
169 }
170
171 diffKeyV.clear();
172 std::vector<std::string> otherk;
173 other.GetAllKey(otherk);
174
175 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
176 for (const auto &iter : otherk) {
177 ABILITYBASE_LOGD("iter:%{public}s,Val:%{public}s", iter.c_str(), other.GetValue(iter).c_str());
178 // Insert new content directly
179 auto pair = configParameter_.insert(std::make_pair(iter, other.GetValue(iter)));
180 if (pair.second) {
181 diffKeyV.push_back(iter); // One of the changes this time
182 continue;
183 }
184 // Compare what you already have
185 if (!other.GetValue(iter).empty() && other.GetValue(iter) != GetValue(iter)) {
186 diffKeyV.push_back(iter);
187 }
188 }
189 }
190
Merge(const std::vector<std::string> & diffKeyV,const Configuration & other)191 void Configuration::Merge(const std::vector<std::string> &diffKeyV, const Configuration &other)
192 {
193 if (diffKeyV.empty()) {
194 return;
195 }
196
197 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
198 for (const auto &mergeItemKey : diffKeyV) {
199 auto myItem = GetValue(mergeItemKey);
200 auto otherItem = other.GetValue(mergeItemKey);
201 // myItem possible empty
202 if (!otherItem.empty() && otherItem != myItem) {
203 configParameter_[mergeItemKey] = otherItem;
204 }
205 }
206 }
207
RemoveItem(int displayId,const std::string & key)208 int Configuration::RemoveItem(int displayId, const std::string &key)
209 {
210 if (key.empty()) {
211 return 0;
212 }
213
214 std::string getKey;
215 if (!MakeTheKey(getKey, displayId, key)) {
216 return 0;
217 }
218
219 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
220 return configParameter_.erase(getKey);
221 }
222
AddItem(const std::string & key,const std::string & value)223 bool Configuration::AddItem(const std::string &key, const std::string &value)
224 {
225 return AddItem(defaultDisplayId_, key, value);
226 }
227
GetItem(const std::string & key) const228 std::string Configuration::GetItem(const std::string &key) const
229 {
230 return GetItem(defaultDisplayId_, key);
231 }
232
RemoveItem(const std::string & key)233 int Configuration::RemoveItem(const std::string &key)
234 {
235 return RemoveItem(defaultDisplayId_, key);
236 }
237
GetName() const238 const std::string Configuration::GetName() const
239 {
240 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
241 json configArray(configParameter_);
242 return configArray.dump();
243 }
244
ReadFromParcel(Parcel & parcel)245 bool Configuration::ReadFromParcel(Parcel &parcel)
246 {
247 ABILITYBASE_LOGD("ReadFromParcel");
248 defaultDisplayId_ = parcel.ReadInt32();
249 int32_t configSize = parcel.ReadInt32();
250 std::vector<std::string> keys;
251 std::vector<std::string> values;
252 keys.clear();
253 values.clear();
254 if (!parcel.ReadStringVector(&keys)) {
255 ABILITYBASE_LOGE("read keys failed");
256 return false;
257 }
258 if (!parcel.ReadStringVector(&values)) {
259 ABILITYBASE_LOGE("read values failed");
260 return false;
261 }
262 size_t keySize = keys.size();
263 size_t valueSize = values.size();
264 if (keySize != valueSize || configSize != (int32_t)valueSize || configSize > CYCLE_LIMIT) {
265 ABILITYBASE_LOGE("invalid size");
266 return false;
267 }
268
269 std::string key;
270 std::string val;
271 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
272 for (int32_t i = 0; i < configSize; i++) {
273 key = keys.at(i);
274 val = values.at(i);
275 configParameter_.emplace(key, val);
276 }
277 return true;
278 }
279
Unmarshalling(Parcel & parcel)280 Configuration *Configuration::Unmarshalling(Parcel &parcel)
281 {
282 Configuration *Configuration = new (std::nothrow) OHOS::AppExecFwk::Configuration();
283 if (Configuration && !Configuration->ReadFromParcel(parcel)) {
284 delete Configuration;
285 Configuration = nullptr;
286 }
287 return Configuration;
288 }
289
Marshalling(Parcel & parcel) const290 bool Configuration::Marshalling(Parcel &parcel) const
291 {
292 ABILITYBASE_LOGD("called");
293 std::vector<std::string> keys;
294 std::vector<std::string> values;
295 keys.clear();
296 values.clear();
297
298 parcel.WriteInt32(defaultDisplayId_);
299
300 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
301 parcel.WriteInt32(configParameter_.size());
302 for (const auto &config : configParameter_) {
303 keys.emplace_back(config.first);
304 values.emplace_back(config.second);
305 }
306
307 parcel.WriteStringVector(keys);
308 parcel.WriteStringVector(values);
309 return true;
310 }
311
FilterDuplicates(const Configuration & other)312 void Configuration::FilterDuplicates(const Configuration &other)
313 {
314 if (other.GetItemSize() == 0) {
315 return;
316 }
317 std::vector<std::string> otherk;
318 other.GetAllKey(otherk);
319
320 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
321 for (const auto &iter : otherk) {
322 auto myItem = GetValue(iter);
323 auto otherItem = other.GetValue(iter);
324 // myItem possible empty
325 if (!otherItem.empty() && !myItem.empty()) {
326 configParameter_.erase(iter);
327 }
328 }
329 }
330 } // namespace AppExecFwk
331 } // namespace OHOS
332