1e0857b17Sopenharmony_ci/*
2e0857b17Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3e0857b17Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4e0857b17Sopenharmony_ci * you may not use this file except in compliance with the License.
5e0857b17Sopenharmony_ci * You may obtain a copy of the License at
6e0857b17Sopenharmony_ci *
7e0857b17Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8e0857b17Sopenharmony_ci *
9e0857b17Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10e0857b17Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11e0857b17Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12e0857b17Sopenharmony_ci * See the License for the specific language governing permissions and
13e0857b17Sopenharmony_ci * limitations under the License.
14e0857b17Sopenharmony_ci */
15e0857b17Sopenharmony_ci
16e0857b17Sopenharmony_ci#include "configuration.h"
17e0857b17Sopenharmony_ci
18e0857b17Sopenharmony_ci#include <mutex>
19e0857b17Sopenharmony_ci#include <nlohmann/json.hpp>
20e0857b17Sopenharmony_ci
21e0857b17Sopenharmony_ci#include "ability_base_log_wrapper.h"
22e0857b17Sopenharmony_ci#include "string_ex.h"
23e0857b17Sopenharmony_ci
24e0857b17Sopenharmony_cinamespace OHOS {
25e0857b17Sopenharmony_cinamespace AppExecFwk {
26e0857b17Sopenharmony_cinamespace {
27e0857b17Sopenharmony_ciconstexpr int CYCLE_LIMIT = 1000;
28e0857b17Sopenharmony_ci}
29e0857b17Sopenharmony_ciusing json = nlohmann::json;
30e0857b17Sopenharmony_ciConfiguration::Configuration()
31e0857b17Sopenharmony_ci{}
32e0857b17Sopenharmony_ci
33e0857b17Sopenharmony_ciConfiguration::Configuration(const Configuration &other) : defaultDisplayId_(other.defaultDisplayId_)
34e0857b17Sopenharmony_ci{
35e0857b17Sopenharmony_ci    std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
36e0857b17Sopenharmony_ci    configParameter_ = other.configParameter_;
37e0857b17Sopenharmony_ci}
38e0857b17Sopenharmony_ci
39e0857b17Sopenharmony_ciConfiguration& Configuration::operator=(const Configuration &other)
40e0857b17Sopenharmony_ci{
41e0857b17Sopenharmony_ci    if (this == &other) {
42e0857b17Sopenharmony_ci        return *this;
43e0857b17Sopenharmony_ci    }
44e0857b17Sopenharmony_ci
45e0857b17Sopenharmony_ci    defaultDisplayId_ = other.defaultDisplayId_;
46e0857b17Sopenharmony_ci
47e0857b17Sopenharmony_ci    std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
48e0857b17Sopenharmony_ci    configParameter_.clear();
49e0857b17Sopenharmony_ci    configParameter_ = other.configParameter_;
50e0857b17Sopenharmony_ci    return *this;
51e0857b17Sopenharmony_ci}
52e0857b17Sopenharmony_ci
53e0857b17Sopenharmony_ciConfiguration::~Configuration()
54e0857b17Sopenharmony_ci{}
55e0857b17Sopenharmony_ci
56e0857b17Sopenharmony_cibool Configuration::MakeTheKey(std::string &getKey, int id, const std::string &param) const
57e0857b17Sopenharmony_ci{
58e0857b17Sopenharmony_ci    if (param.empty()) {
59e0857b17Sopenharmony_ci        return false;
60e0857b17Sopenharmony_ci    }
61e0857b17Sopenharmony_ci
62e0857b17Sopenharmony_ci    const std::vector<std::string> SystemConfigurationKeyStore {
63e0857b17Sopenharmony_ci        OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE,
64e0857b17Sopenharmony_ci        OHOS::AAFwk::GlobalConfigurationKey::IS_PREFERRED_LANGUAGE,
65e0857b17Sopenharmony_ci        OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_HOUR,
66e0857b17Sopenharmony_ci        OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE,
67e0857b17Sopenharmony_ci        OHOS::AAFwk::GlobalConfigurationKey::INPUT_POINTER_DEVICE,
68e0857b17Sopenharmony_ci        OHOS::AAFwk::GlobalConfigurationKey::DEVICE_TYPE,
69e0857b17Sopenharmony_ci        OHOS::AAFwk::GlobalConfigurationKey::THEME,
70e0857b17Sopenharmony_ci        OHOS::AAFwk::GlobalConfigurationKey::THEME_ID,
71e0857b17Sopenharmony_ci        OHOS::AAFwk::GlobalConfigurationKey::COLORMODE_IS_SET_BY_SA,
72e0857b17Sopenharmony_ci        OHOS::AAFwk::GlobalConfigurationKey::COLORMODE_IS_SET_BY_APP,
73e0857b17Sopenharmony_ci        OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_FONT_SIZE_SCALE,
74e0857b17Sopenharmony_ci        OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_FONT_WEIGHT_SCALE,
75e0857b17Sopenharmony_ci        OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_MCC,
76e0857b17Sopenharmony_ci        OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_MNC,
77e0857b17Sopenharmony_ci        OHOS::AppExecFwk::ConfigurationInner::APPLICATION_DIRECTION,
78e0857b17Sopenharmony_ci        OHOS::AppExecFwk::ConfigurationInner::APPLICATION_DENSITYDPI,
79e0857b17Sopenharmony_ci        OHOS::AppExecFwk::ConfigurationInner::APPLICATION_DISPLAYID,
80e0857b17Sopenharmony_ci        OHOS::AppExecFwk::ConfigurationInner::APPLICATION_FONT,
81e0857b17Sopenharmony_ci        OHOS::AAFwk::GlobalConfigurationKey::APP_FONT_SIZE_SCALE,
82e0857b17Sopenharmony_ci        OHOS::AAFwk::GlobalConfigurationKey::APP_FONT_MAX_SCALE,
83e0857b17Sopenharmony_ci    };
84e0857b17Sopenharmony_ci    if (std::find(SystemConfigurationKeyStore.begin(), SystemConfigurationKeyStore.end(), param) ==
85e0857b17Sopenharmony_ci        SystemConfigurationKeyStore.end()) {
86e0857b17Sopenharmony_ci        return false;
87e0857b17Sopenharmony_ci    }
88e0857b17Sopenharmony_ci
89e0857b17Sopenharmony_ci    getKey.clear();
90e0857b17Sopenharmony_ci    getKey += std::to_string(id);
91e0857b17Sopenharmony_ci    getKey += ConfigurationInner::CONNECTION_SYMBOL;
92e0857b17Sopenharmony_ci    getKey += param;
93e0857b17Sopenharmony_ci    ABILITYBASE_LOGD("key: %{public}s", getKey.c_str());
94e0857b17Sopenharmony_ci
95e0857b17Sopenharmony_ci    return true;
96e0857b17Sopenharmony_ci}
97e0857b17Sopenharmony_ci
98e0857b17Sopenharmony_cibool Configuration::AddItem(int displayId, const std::string &key, const std::string &value)
99e0857b17Sopenharmony_ci{
100e0857b17Sopenharmony_ci    if (key.empty() || value.empty()) {
101e0857b17Sopenharmony_ci        return false;
102e0857b17Sopenharmony_ci    }
103e0857b17Sopenharmony_ci
104e0857b17Sopenharmony_ci    std::string getKey;
105e0857b17Sopenharmony_ci    if (!MakeTheKey(getKey, displayId, key)) {
106e0857b17Sopenharmony_ci        return false;
107e0857b17Sopenharmony_ci    }
108e0857b17Sopenharmony_ci
109e0857b17Sopenharmony_ci    std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
110e0857b17Sopenharmony_ci    configParameter_[getKey] = value;
111e0857b17Sopenharmony_ci    return true;
112e0857b17Sopenharmony_ci}
113e0857b17Sopenharmony_ci
114e0857b17Sopenharmony_cistd::string Configuration::GetItem(int displayId, const std::string &key) const
115e0857b17Sopenharmony_ci{
116e0857b17Sopenharmony_ci    if (key.empty()) {
117e0857b17Sopenharmony_ci        return ConfigurationInner::EMPTY_STRING;
118e0857b17Sopenharmony_ci    }
119e0857b17Sopenharmony_ci
120e0857b17Sopenharmony_ci    std::string getKey;
121e0857b17Sopenharmony_ci    if (!MakeTheKey(getKey, displayId, key)) {
122e0857b17Sopenharmony_ci        return ConfigurationInner::EMPTY_STRING;
123e0857b17Sopenharmony_ci    }
124e0857b17Sopenharmony_ci
125e0857b17Sopenharmony_ci    std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
126e0857b17Sopenharmony_ci    auto iter = configParameter_.find(getKey);
127e0857b17Sopenharmony_ci    if (iter != configParameter_.end()) {
128e0857b17Sopenharmony_ci        return iter->second;
129e0857b17Sopenharmony_ci    }
130e0857b17Sopenharmony_ci
131e0857b17Sopenharmony_ci    return ConfigurationInner::EMPTY_STRING;
132e0857b17Sopenharmony_ci}
133e0857b17Sopenharmony_ci
134e0857b17Sopenharmony_ciint Configuration::GetItemSize() const
135e0857b17Sopenharmony_ci{
136e0857b17Sopenharmony_ci    std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
137e0857b17Sopenharmony_ci    return configParameter_.size();
138e0857b17Sopenharmony_ci}
139e0857b17Sopenharmony_ci
140e0857b17Sopenharmony_civoid Configuration::GetAllKey(std::vector<std::string> &keychain) const
141e0857b17Sopenharmony_ci{
142e0857b17Sopenharmony_ci    keychain.clear();
143e0857b17Sopenharmony_ci
144e0857b17Sopenharmony_ci    std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
145e0857b17Sopenharmony_ci    for (const auto &it :configParameter_) {
146e0857b17Sopenharmony_ci        keychain.push_back(it.first);
147e0857b17Sopenharmony_ci    }
148e0857b17Sopenharmony_ci}
149e0857b17Sopenharmony_ci
150e0857b17Sopenharmony_cistd::string Configuration::GetValue(const std::string &key) const
151e0857b17Sopenharmony_ci{
152e0857b17Sopenharmony_ci    std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
153e0857b17Sopenharmony_ci    auto iter = configParameter_.find(key);
154e0857b17Sopenharmony_ci    if (iter != configParameter_.end()) {
155e0857b17Sopenharmony_ci        return iter->second;
156e0857b17Sopenharmony_ci    }
157e0857b17Sopenharmony_ci
158e0857b17Sopenharmony_ci    return ConfigurationInner::EMPTY_STRING;
159e0857b17Sopenharmony_ci}
160e0857b17Sopenharmony_ci
161e0857b17Sopenharmony_civoid Configuration::CompareDifferent(std::vector<std::string> &diffKeyV, const Configuration &other)
162e0857b17Sopenharmony_ci{
163e0857b17Sopenharmony_ci    if (other.GetItemSize() == 0) {
164e0857b17Sopenharmony_ci        return;
165e0857b17Sopenharmony_ci    }
166e0857b17Sopenharmony_ci
167e0857b17Sopenharmony_ci    diffKeyV.clear();
168e0857b17Sopenharmony_ci    std::vector<std::string> otherk;
169e0857b17Sopenharmony_ci    other.GetAllKey(otherk);
170e0857b17Sopenharmony_ci
171e0857b17Sopenharmony_ci    std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
172e0857b17Sopenharmony_ci    for (const auto &iter : otherk) {
173e0857b17Sopenharmony_ci        ABILITYBASE_LOGD("iter:%{public}s,Val:%{public}s", iter.c_str(), other.GetValue(iter).c_str());
174e0857b17Sopenharmony_ci        // Insert new content directly
175e0857b17Sopenharmony_ci        auto pair = configParameter_.insert(std::make_pair(iter, other.GetValue(iter)));
176e0857b17Sopenharmony_ci        if (pair.second) {
177e0857b17Sopenharmony_ci            diffKeyV.push_back(iter); // One of the changes this time
178e0857b17Sopenharmony_ci            continue;
179e0857b17Sopenharmony_ci        }
180e0857b17Sopenharmony_ci        // Compare what you already have
181e0857b17Sopenharmony_ci        if (!other.GetValue(iter).empty() && other.GetValue(iter) != GetValue(iter)) {
182e0857b17Sopenharmony_ci            diffKeyV.push_back(iter);
183e0857b17Sopenharmony_ci        }
184e0857b17Sopenharmony_ci    }
185e0857b17Sopenharmony_ci}
186e0857b17Sopenharmony_ci
187e0857b17Sopenharmony_civoid Configuration::Merge(const std::vector<std::string> &diffKeyV, const Configuration &other)
188e0857b17Sopenharmony_ci{
189e0857b17Sopenharmony_ci    if (diffKeyV.empty()) {
190e0857b17Sopenharmony_ci        return;
191e0857b17Sopenharmony_ci    }
192e0857b17Sopenharmony_ci
193e0857b17Sopenharmony_ci    std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
194e0857b17Sopenharmony_ci    for (const auto &mergeItemKey : diffKeyV) {
195e0857b17Sopenharmony_ci        auto myItem = GetValue(mergeItemKey);
196e0857b17Sopenharmony_ci        auto otherItem = other.GetValue(mergeItemKey);
197e0857b17Sopenharmony_ci        // myItem possible empty
198e0857b17Sopenharmony_ci        if (!otherItem.empty() && otherItem != myItem) {
199e0857b17Sopenharmony_ci            configParameter_[mergeItemKey] = otherItem;
200e0857b17Sopenharmony_ci        }
201e0857b17Sopenharmony_ci    }
202e0857b17Sopenharmony_ci}
203e0857b17Sopenharmony_ci
204e0857b17Sopenharmony_ciint Configuration::RemoveItem(int displayId, const std::string &key)
205e0857b17Sopenharmony_ci{
206e0857b17Sopenharmony_ci    if (key.empty()) {
207e0857b17Sopenharmony_ci        return 0;
208e0857b17Sopenharmony_ci    }
209e0857b17Sopenharmony_ci
210e0857b17Sopenharmony_ci    std::string getKey;
211e0857b17Sopenharmony_ci    if (!MakeTheKey(getKey, displayId, key)) {
212e0857b17Sopenharmony_ci        return 0;
213e0857b17Sopenharmony_ci    }
214e0857b17Sopenharmony_ci
215e0857b17Sopenharmony_ci    std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
216e0857b17Sopenharmony_ci    return configParameter_.erase(getKey);
217e0857b17Sopenharmony_ci}
218e0857b17Sopenharmony_ci
219e0857b17Sopenharmony_cibool Configuration::AddItem(const std::string &key, const std::string &value)
220e0857b17Sopenharmony_ci{
221e0857b17Sopenharmony_ci    return AddItem(defaultDisplayId_, key, value);
222e0857b17Sopenharmony_ci}
223e0857b17Sopenharmony_ci
224e0857b17Sopenharmony_cistd::string Configuration::GetItem(const std::string &key) const
225e0857b17Sopenharmony_ci{
226e0857b17Sopenharmony_ci    return GetItem(defaultDisplayId_, key);
227e0857b17Sopenharmony_ci}
228e0857b17Sopenharmony_ci
229e0857b17Sopenharmony_ciint Configuration::RemoveItem(const std::string &key)
230e0857b17Sopenharmony_ci{
231e0857b17Sopenharmony_ci    return RemoveItem(defaultDisplayId_, key);
232e0857b17Sopenharmony_ci}
233e0857b17Sopenharmony_ci
234e0857b17Sopenharmony_ciconst std::string Configuration::GetName() const
235e0857b17Sopenharmony_ci{
236e0857b17Sopenharmony_ci    std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
237e0857b17Sopenharmony_ci    json configArray(configParameter_);
238e0857b17Sopenharmony_ci    return configArray.dump();
239e0857b17Sopenharmony_ci}
240e0857b17Sopenharmony_ci
241e0857b17Sopenharmony_cibool Configuration::ReadFromParcel(Parcel &parcel)
242e0857b17Sopenharmony_ci{
243e0857b17Sopenharmony_ci    ABILITYBASE_LOGD("ReadFromParcel");
244e0857b17Sopenharmony_ci    defaultDisplayId_ = parcel.ReadInt32();
245e0857b17Sopenharmony_ci    int32_t configSize = parcel.ReadInt32();
246e0857b17Sopenharmony_ci    std::vector<std::string> keys;
247e0857b17Sopenharmony_ci    std::vector<std::string> values;
248e0857b17Sopenharmony_ci    keys.clear();
249e0857b17Sopenharmony_ci    values.clear();
250e0857b17Sopenharmony_ci    if (!parcel.ReadStringVector(&keys)) {
251e0857b17Sopenharmony_ci        ABILITYBASE_LOGE("read keys failed");
252e0857b17Sopenharmony_ci        return false;
253e0857b17Sopenharmony_ci    }
254e0857b17Sopenharmony_ci    if (!parcel.ReadStringVector(&values)) {
255e0857b17Sopenharmony_ci        ABILITYBASE_LOGE("read values failed");
256e0857b17Sopenharmony_ci        return false;
257e0857b17Sopenharmony_ci    }
258e0857b17Sopenharmony_ci    size_t keySize = keys.size();
259e0857b17Sopenharmony_ci    size_t valueSize = values.size();
260e0857b17Sopenharmony_ci    if (keySize != valueSize || configSize != (int32_t)valueSize || configSize > CYCLE_LIMIT) {
261e0857b17Sopenharmony_ci        ABILITYBASE_LOGE("invalid size");
262e0857b17Sopenharmony_ci        return false;
263e0857b17Sopenharmony_ci    }
264e0857b17Sopenharmony_ci
265e0857b17Sopenharmony_ci    std::string key;
266e0857b17Sopenharmony_ci    std::string val;
267e0857b17Sopenharmony_ci    std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
268e0857b17Sopenharmony_ci    for (int32_t i = 0; i < configSize; i++) {
269e0857b17Sopenharmony_ci        key = keys.at(i);
270e0857b17Sopenharmony_ci        val = values.at(i);
271e0857b17Sopenharmony_ci        configParameter_.emplace(key, val);
272e0857b17Sopenharmony_ci    }
273e0857b17Sopenharmony_ci    return true;
274e0857b17Sopenharmony_ci}
275e0857b17Sopenharmony_ci
276e0857b17Sopenharmony_ciConfiguration *Configuration::Unmarshalling(Parcel &parcel)
277e0857b17Sopenharmony_ci{
278e0857b17Sopenharmony_ci    Configuration *Configuration = new (std::nothrow) OHOS::AppExecFwk::Configuration();
279e0857b17Sopenharmony_ci    if (Configuration && !Configuration->ReadFromParcel(parcel)) {
280e0857b17Sopenharmony_ci        delete Configuration;
281e0857b17Sopenharmony_ci        Configuration = nullptr;
282e0857b17Sopenharmony_ci    }
283e0857b17Sopenharmony_ci    return Configuration;
284e0857b17Sopenharmony_ci}
285e0857b17Sopenharmony_ci
286e0857b17Sopenharmony_cibool Configuration::Marshalling(Parcel &parcel) const
287e0857b17Sopenharmony_ci{
288e0857b17Sopenharmony_ci    ABILITYBASE_LOGD("called");
289e0857b17Sopenharmony_ci    std::vector<std::string> keys;
290e0857b17Sopenharmony_ci    std::vector<std::string> values;
291e0857b17Sopenharmony_ci    keys.clear();
292e0857b17Sopenharmony_ci    values.clear();
293e0857b17Sopenharmony_ci
294e0857b17Sopenharmony_ci    parcel.WriteInt32(defaultDisplayId_);
295e0857b17Sopenharmony_ci
296e0857b17Sopenharmony_ci    std::lock_guard<std::recursive_mutex> lock(configParameterMutex_);
297e0857b17Sopenharmony_ci    parcel.WriteInt32(configParameter_.size());
298e0857b17Sopenharmony_ci    for (const auto &config : configParameter_) {
299e0857b17Sopenharmony_ci        keys.emplace_back(config.first);
300e0857b17Sopenharmony_ci        values.emplace_back(config.second);
301e0857b17Sopenharmony_ci    }
302e0857b17Sopenharmony_ci
303e0857b17Sopenharmony_ci    parcel.WriteStringVector(keys);
304e0857b17Sopenharmony_ci    parcel.WriteStringVector(values);
305e0857b17Sopenharmony_ci    return true;
306e0857b17Sopenharmony_ci}
307e0857b17Sopenharmony_ci}  // namespace AppExecFwk
308e0857b17Sopenharmony_ci}  // namespace OHOS
309