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