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 <nlohmann/json.hpp>
19
20 #include "ability_base_log_wrapper.h"
21 #include "string_ex.h"
22
23 namespace OHOS {
24 namespace AppExecFwk {
25 namespace {
26 constexpr int CYCLE_LIMIT = 1000;
27 }
28 using json = nlohmann::json;
Configuration()29 Configuration::Configuration()
30 {}
31
Configuration(const Configuration & other)32 Configuration::Configuration(const Configuration &other) : defaultDisplayId_(other.defaultDisplayId_)
33 {
34 configParameter_ = other.configParameter_;
35 }
36
operator =(const Configuration & other)37 Configuration& Configuration::operator=(const Configuration &other)
38 {
39 if (this == &other) {
40 return *this;
41 }
42
43 defaultDisplayId_ = other.defaultDisplayId_;
44 configParameter_.clear();
45 configParameter_ = other.configParameter_;
46 return *this;
47 }
48
~Configuration()49 Configuration::~Configuration()
50 {}
51
MakeTheKey(std::string & getKey,int id,const std::string & param) const52 bool Configuration::MakeTheKey(std::string &getKey, int id, const std::string ¶m) const
53 {
54 if (param.empty()) {
55 return false;
56 }
57
58 if (std::find(ConfigurationInner::SystemConfigurationKeyStore.begin(),
59 ConfigurationInner::SystemConfigurationKeyStore.end(), param) ==
60 ConfigurationInner::SystemConfigurationKeyStore.end()) {
61 return false;
62 }
63
64 getKey.clear();
65 getKey += std::to_string(id);
66 getKey += ConfigurationInner::CONNECTION_SYMBOL;
67 getKey += param;
68 ABILITYBASE_LOGD(" getKey [%{public}s]", getKey.c_str());
69
70 return true;
71 }
72
AddItem(int displayId,const std::string & key,const std::string & value)73 bool Configuration::AddItem(int displayId, const std::string &key, const std::string &value)
74 {
75 if (key.empty() || value.empty()) {
76 return false;
77 }
78
79 std::string getKey;
80 if (!MakeTheKey(getKey, displayId, key)) {
81 return false;
82 }
83
84 configParameter_[getKey] = value;
85 return true;
86 }
87
GetItem(int displayId,const std::string & key) const88 std::string Configuration::GetItem(int displayId, const std::string &key) const
89 {
90 if (key.empty()) {
91 return ConfigurationInner::EMPTY_STRING;
92 }
93
94 std::string getKey;
95 if (!MakeTheKey(getKey, displayId, key)) {
96 return ConfigurationInner::EMPTY_STRING;
97 }
98
99 auto iter = configParameter_.find(getKey);
100 if (iter != configParameter_.end()) {
101 return iter->second;
102 }
103
104 return ConfigurationInner::EMPTY_STRING;
105 }
106
GetItemSize() const107 int Configuration::GetItemSize() const
108 {
109 return configParameter_.size();
110 }
111
GetAllKey(std::vector<std::string> & keychain) const112 void Configuration::GetAllKey(std::vector<std::string> &keychain) const
113 {
114 keychain.clear();
115 for (const auto &it :configParameter_) {
116 keychain.push_back(it.first);
117 }
118 }
119
GetValue(const std::string & key) const120 std::string Configuration::GetValue(const std::string &key) const
121 {
122 auto iter = configParameter_.find(key);
123 if (iter != configParameter_.end()) {
124 return iter->second;
125 }
126
127 return ConfigurationInner::EMPTY_STRING;
128 }
129
CompareDifferent(std::vector<std::string> & diffKeyV,const Configuration & other)130 void Configuration::CompareDifferent(std::vector<std::string> &diffKeyV, const Configuration &other)
131 {
132 if (other.GetItemSize() == 0) {
133 return;
134 }
135
136 diffKeyV.clear();
137 std::vector<std::string> otherk;
138 other.GetAllKey(otherk);
139 for (const auto &iter : otherk) {
140 ABILITYBASE_LOGW(" iter : [%{public}s] | Val: [%{public}s]", iter.c_str(), other.GetValue(iter).c_str());
141 // Insert new content directly
142 auto pair = configParameter_.insert(std::make_pair(iter, other.GetValue(iter)));
143 if (pair.second) {
144 diffKeyV.push_back(iter); // One of the changes this time
145 continue;
146 }
147 // Compare what you already have
148 if (!other.GetValue(iter).empty() && other.GetValue(iter) != GetValue(iter)) {
149 diffKeyV.push_back(iter);
150 }
151 }
152 }
153
Merge(const std::vector<std::string> & diffKeyV,const Configuration & other)154 void Configuration::Merge(const std::vector<std::string> &diffKeyV, const Configuration &other)
155 {
156 if (diffKeyV.empty()) {
157 return;
158 }
159 for (const auto &mergeItemKey : diffKeyV) {
160 auto myItem = GetValue(mergeItemKey);
161 auto otherItem = other.GetValue(mergeItemKey);
162 // myItem possible empty
163 if (!otherItem.empty() && otherItem != myItem) {
164 configParameter_[mergeItemKey] = otherItem;
165 }
166 }
167 }
168
RemoveItem(int displayId,const std::string & key)169 int Configuration::RemoveItem(int displayId, const std::string &key)
170 {
171 if (key.empty()) {
172 return 0;
173 }
174
175 std::string getKey;
176 if (!MakeTheKey(getKey, displayId, key)) {
177 return 0;
178 }
179
180 return configParameter_.erase(getKey);
181 }
182
AddItem(const std::string & key,const std::string & value)183 bool Configuration::AddItem(const std::string &key, const std::string &value)
184 {
185 return AddItem(defaultDisplayId_, key, value);
186 }
187
GetItem(const std::string & key) const188 std::string Configuration::GetItem(const std::string &key) const
189 {
190 return GetItem(defaultDisplayId_, key);
191 }
192
RemoveItem(const std::string & key)193 int Configuration::RemoveItem(const std::string &key)
194 {
195 return RemoveItem(defaultDisplayId_, key);
196 }
197
GetName() const198 const std::string& Configuration::GetName() const
199 {
200 json configArray(configParameter_);
201 toStrintg_ = configArray.dump();
202 return toStrintg_;
203 }
204
ReadFromParcel(Parcel & parcel)205 bool Configuration::ReadFromParcel(Parcel &parcel)
206 {
207 ABILITYBASE_LOGD("ReadFromParcel");
208 defaultDisplayId_ = parcel.ReadInt32();
209 int32_t configSize = parcel.ReadInt32();
210 std::vector<std::string> keys;
211 std::vector<std::string> values;
212 keys.clear();
213 values.clear();
214 if (!parcel.ReadStringVector(&keys)) {
215 ABILITYBASE_LOGE("ReadStringVector for keys failed.");
216 return false;
217 }
218 if (!parcel.ReadStringVector(&values)) {
219 ABILITYBASE_LOGE("ReadStringVector for values failed.");
220 return false;
221 }
222 size_t keySize = keys.size();
223 size_t valueSize = values.size();
224 if (keySize != valueSize || configSize != (int32_t)valueSize || configSize > CYCLE_LIMIT) {
225 ABILITYBASE_LOGE("ReadFromParcel failed, invalid size.");
226 return false;
227 }
228 std::string key;
229 std::string val;
230 for (int32_t i = 0; i < configSize; i++) {
231 key = keys.at(i);
232 val = values.at(i);
233 configParameter_.emplace(key, val);
234 }
235 return true;
236 }
237
Unmarshalling(Parcel & parcel)238 Configuration *Configuration::Unmarshalling(Parcel &parcel)
239 {
240 Configuration *Configuration = new (std::nothrow) OHOS::AppExecFwk::Configuration();
241 if (Configuration && !Configuration->ReadFromParcel(parcel)) {
242 delete Configuration;
243 Configuration = nullptr;
244 }
245 return Configuration;
246 }
247
Marshalling(Parcel & parcel) const248 bool Configuration::Marshalling(Parcel &parcel) const
249 {
250 ABILITYBASE_LOGW("Marshalling");
251 std::vector<std::string> keys;
252 std::vector<std::string> values;
253 keys.clear();
254 values.clear();
255 parcel.WriteInt32(defaultDisplayId_);
256 parcel.WriteInt32(configParameter_.size());
257 for (const auto &config : configParameter_) {
258 keys.emplace_back(config.first);
259 values.emplace_back(config.second);
260 }
261
262 parcel.WriteStringVector(keys);
263 parcel.WriteStringVector(values);
264 return true;
265 }
266 } // namespace AppExecFwk
267 } // namespace OHOS
268