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