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_HOUR,
66 OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE,
67 OHOS::AAFwk::GlobalConfigurationKey::INPUT_POINTER_DEVICE,
68 OHOS::AAFwk::GlobalConfigurationKey::DEVICE_TYPE,
69 OHOS::AAFwk::GlobalConfigurationKey::THEME,
70 OHOS::AAFwk::GlobalConfigurationKey::THEME_ID,
71 OHOS::AAFwk::GlobalConfigurationKey::THEME_ICON,
72 OHOS::AAFwk::GlobalConfigurationKey::COLORMODE_IS_SET_BY_SA,
73 OHOS::AAFwk::GlobalConfigurationKey::COLORMODE_IS_SET_BY_APP,
74 OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_FONT_ID,
75 OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_FONT_SIZE_SCALE,
76 OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_FONT_WEIGHT_SCALE,
77 OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_MCC,
78 OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_MNC,
79 OHOS::AppExecFwk::ConfigurationInner::APPLICATION_DIRECTION,
80 OHOS::AppExecFwk::ConfigurationInner::APPLICATION_DENSITYDPI,
81 OHOS::AppExecFwk::ConfigurationInner::APPLICATION_DISPLAYID,
82 OHOS::AppExecFwk::ConfigurationInner::APPLICATION_FONT,
83 OHOS::AAFwk::GlobalConfigurationKey::APP_FONT_SIZE_SCALE,
84 OHOS::AAFwk::GlobalConfigurationKey::APP_FONT_MAX_SCALE,
85 };
86 if (std::find(SystemConfigurationKeyStore.begin(), SystemConfigurationKeyStore.end(), param) ==
87 SystemConfigurationKeyStore.end()) {
88 return false;
89 }
90
91 getKey.clear();
92 getKey += std::to_string(id);
93 getKey += ConfigurationInner::CONNECTION_SYMBOL;
94 getKey += param;
95 ABILITYBASE_LOGD("key: %{public}s", getKey.c_str());
96
97 return true;
98 }
99
AddItem(int displayId,const std::string & key,const std::string & value)100 bool Configuration::AddItem(int displayId, const std::string &key, const std::string &value)
101 {
102 if (key.empty() || value.empty()) {
103 return false;
104 }
105
106 std::string getKey;
107 if (!MakeTheKey(getKey, displayId, key)) {
108 return false;
109 }
110
111 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
112 configParameter_[getKey] = value;
113 return true;
114 }
115
GetItem(int displayId,const std::string & key) const116 std::string Configuration::GetItem(int displayId, const std::string &key) const
117 {
118 if (key.empty()) {
119 return ConfigurationInner::EMPTY_STRING;
120 }
121
122 std::string getKey;
123 if (!MakeTheKey(getKey, displayId, key)) {
124 return ConfigurationInner::EMPTY_STRING;
125 }
126
127 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
128 auto iter = configParameter_.find(getKey);
129 if (iter != configParameter_.end()) {
130 return iter->second;
131 }
132
133 return ConfigurationInner::EMPTY_STRING;
134 }
135
GetItemSize() const136 int Configuration::GetItemSize() const
137 {
138 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
139 return configParameter_.size();
140 }
141
GetAllKey(std::vector<std::string> & keychain) const142 void Configuration::GetAllKey(std::vector<std::string> &keychain) const
143 {
144 keychain.clear();
145
146 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
147 for (const auto &it :configParameter_) {
148 keychain.push_back(it.first);
149 }
150 }
151
GetValue(const std::string & key) const152 std::string Configuration::GetValue(const std::string &key) const
153 {
154 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
155 auto iter = configParameter_.find(key);
156 if (iter != configParameter_.end()) {
157 return iter->second;
158 }
159
160 return ConfigurationInner::EMPTY_STRING;
161 }
162
CompareDifferent(std::vector<std::string> & diffKeyV,const Configuration & other)163 void Configuration::CompareDifferent(std::vector<std::string> &diffKeyV, const Configuration &other)
164 {
165 if (other.GetItemSize() == 0) {
166 return;
167 }
168
169 diffKeyV.clear();
170 std::vector<std::string> otherk;
171 other.GetAllKey(otherk);
172
173 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
174 for (const auto &iter : otherk) {
175 ABILITYBASE_LOGD("iter:%{public}s,Val:%{public}s", iter.c_str(), other.GetValue(iter).c_str());
176 // Insert new content directly
177 auto pair = configParameter_.insert(std::make_pair(iter, other.GetValue(iter)));
178 if (pair.second) {
179 diffKeyV.push_back(iter); // One of the changes this time
180 continue;
181 }
182 // Compare what you already have
183 if (!other.GetValue(iter).empty() && other.GetValue(iter) != GetValue(iter)) {
184 diffKeyV.push_back(iter);
185 }
186 }
187 }
188
Merge(const std::vector<std::string> & diffKeyV,const Configuration & other)189 void Configuration::Merge(const std::vector<std::string> &diffKeyV, const Configuration &other)
190 {
191 if (diffKeyV.empty()) {
192 return;
193 }
194
195 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
196 for (const auto &mergeItemKey : diffKeyV) {
197 auto myItem = GetValue(mergeItemKey);
198 auto otherItem = other.GetValue(mergeItemKey);
199 // myItem possible empty
200 if (!otherItem.empty() && otherItem != myItem) {
201 configParameter_[mergeItemKey] = otherItem;
202 }
203 }
204 }
205
RemoveItem(int displayId,const std::string & key)206 int Configuration::RemoveItem(int displayId, const std::string &key)
207 {
208 if (key.empty()) {
209 return 0;
210 }
211
212 std::string getKey;
213 if (!MakeTheKey(getKey, displayId, key)) {
214 return 0;
215 }
216
217 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
218 return configParameter_.erase(getKey);
219 }
220
AddItem(const std::string & key,const std::string & value)221 bool Configuration::AddItem(const std::string &key, const std::string &value)
222 {
223 return AddItem(defaultDisplayId_, key, value);
224 }
225
GetItem(const std::string & key) const226 std::string Configuration::GetItem(const std::string &key) const
227 {
228 return GetItem(defaultDisplayId_, key);
229 }
230
RemoveItem(const std::string & key)231 int Configuration::RemoveItem(const std::string &key)
232 {
233 return RemoveItem(defaultDisplayId_, key);
234 }
235
GetName() const236 const std::string Configuration::GetName() const
237 {
238 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
239 json configArray(configParameter_);
240 return configArray.dump();
241 }
242
ReadFromParcel(Parcel & parcel)243 bool Configuration::ReadFromParcel(Parcel &parcel)
244 {
245 ABILITYBASE_LOGD("ReadFromParcel");
246 defaultDisplayId_ = parcel.ReadInt32();
247 int32_t configSize = parcel.ReadInt32();
248 std::vector<std::string> keys;
249 std::vector<std::string> values;
250 keys.clear();
251 values.clear();
252 if (!parcel.ReadStringVector(&keys)) {
253 ABILITYBASE_LOGE("read keys failed");
254 return false;
255 }
256 if (!parcel.ReadStringVector(&values)) {
257 ABILITYBASE_LOGE("read values failed");
258 return false;
259 }
260 size_t keySize = keys.size();
261 size_t valueSize = values.size();
262 if (keySize != valueSize || configSize != (int32_t)valueSize || configSize > CYCLE_LIMIT) {
263 ABILITYBASE_LOGE("invalid size");
264 return false;
265 }
266
267 std::string key;
268 std::string val;
269 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
270 for (int32_t i = 0; i < configSize; i++) {
271 key = keys.at(i);
272 val = values.at(i);
273 configParameter_.emplace(key, val);
274 }
275 return true;
276 }
277
Unmarshalling(Parcel & parcel)278 Configuration *Configuration::Unmarshalling(Parcel &parcel)
279 {
280 Configuration *Configuration = new (std::nothrow) OHOS::AppExecFwk::Configuration();
281 if (Configuration && !Configuration->ReadFromParcel(parcel)) {
282 delete Configuration;
283 Configuration = nullptr;
284 }
285 return Configuration;
286 }
287
Marshalling(Parcel & parcel) const288 bool Configuration::Marshalling(Parcel &parcel) const
289 {
290 ABILITYBASE_LOGD("called");
291 std::vector<std::string> keys;
292 std::vector<std::string> values;
293 keys.clear();
294 values.clear();
295
296 parcel.WriteInt32(defaultDisplayId_);
297
298 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
299 parcel.WriteInt32(configParameter_.size());
300 for (const auto &config : configParameter_) {
301 keys.emplace_back(config.first);
302 values.emplace_back(config.second);
303 }
304
305 parcel.WriteStringVector(keys);
306 parcel.WriteStringVector(values);
307 return true;
308 }
309
FilterDuplicates(const Configuration & other)310 void Configuration::FilterDuplicates(const Configuration &other)
311 {
312 if (other.GetItemSize() == 0) {
313 return;
314 }
315 std::vector<std::string> otherk;
316 other.GetAllKey(otherk);
317
318 std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
319 for (const auto &iter : otherk) {
320 auto myItem = GetValue(iter);
321 auto otherItem = other.GetValue(iter);
322 // myItem possible empty
323 if (!otherItem.empty() && !myItem.empty()) {
324 configParameter_.erase(iter);
325 }
326 }
327 }
328 } // namespace AppExecFwk
329 } // namespace OHOS
330