1 /*
2 * Copyright (c) 2023-2024 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 "static_subscriber_data_manager.h"
17
18 #include <unistd.h>
19
20 #include "ces_inner_error_code.h"
21 #include "event_log_wrapper.h"
22 #include "nlohmann/json.hpp"
23
24 namespace OHOS {
25 namespace EventFwk {
26 namespace {
27 constexpr int32_t CHECK_INTERVAL = 100000; // 100ms
28 constexpr int32_t MAX_TIMES = 5; // 5 * 100ms = 500ms
29 constexpr const char *STATIC_SUBSCRIBER_STORAGE_DIR = "/data/service/el1/public/database/common_event_service";
30 const std::string STATIC_SUBSCRIBER_VALUE_DEFAULT = "0";
31 } // namespace
StaticSubscriberDataManager()32 StaticSubscriberDataManager::StaticSubscriberDataManager() {}
33
~StaticSubscriberDataManager()34 StaticSubscriberDataManager::~StaticSubscriberDataManager()
35 {
36 if (kvStorePtr_ != nullptr) {
37 dataManager_.CloseKvStore(appId_, kvStorePtr_);
38 }
39 }
40
GetKvStore()41 DistributedKv::Status StaticSubscriberDataManager::GetKvStore()
42 {
43 DistributedKv::Options options = {
44 .createIfMissing = true,
45 .encrypt = false,
46 .autoSync = false,
47 .syncable = false,
48 .securityLevel = DistributedKv::SecurityLevel::S1,
49 .area = DistributedKv::EL1,
50 .kvStoreType = DistributedKv::KvStoreType::SINGLE_VERSION,
51 .baseDir = STATIC_SUBSCRIBER_STORAGE_DIR
52 };
53
54 DistributedKv::Status status = dataManager_.GetSingleKvStore(options, appId_, storeId_, kvStorePtr_);
55 if (status != DistributedKv::Status::SUCCESS) {
56 EVENT_LOGE("return error: %{public}d", status);
57 }
58 return status;
59 }
60
CheckKvStore()61 bool StaticSubscriberDataManager::CheckKvStore()
62 {
63 if (kvStorePtr_ != nullptr) {
64 return true;
65 }
66 int32_t tryTimes = MAX_TIMES;
67 while (tryTimes > 0) {
68 DistributedKv::Status status = GetKvStore();
69 if (status == DistributedKv::Status::SUCCESS && kvStorePtr_ != nullptr) {
70 return true;
71 }
72 EVENT_LOGI("try times: %{public}d", tryTimes);
73 usleep(CHECK_INTERVAL);
74 tryTimes--;
75 }
76 return kvStorePtr_ != nullptr;
77 }
78
UpdateStaticSubscriberState(const std::map<std::string,std::vector<std::string>> & disableEvents)79 int32_t StaticSubscriberDataManager::UpdateStaticSubscriberState(
80 const std::map<std::string, std::vector<std::string>> &disableEvents)
81 {
82 std::map<std::string, std::vector<std::string>> disableEventsDatabase;
83 std::set<std::string> bundleList;
84 int32_t ret = QueryStaticSubscriberStateData(disableEventsDatabase, bundleList);
85 if (ret != ERR_OK) {
86 EVENT_LOGE("Query static subscriber state data failed.");
87 return ret;
88 }
89
90 std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
91 if (!CheckKvStore()) {
92 EVENT_LOGE("Kvstore is nullptr.");
93 return ERR_NO_INIT;
94 }
95
96 for (auto &disableEventsDatabaseIt : disableEventsDatabase) {
97 DistributedKv::Key key(disableEventsDatabaseIt.first);
98 if (kvStorePtr_->Delete(key) != DistributedKv::Status::SUCCESS) {
99 EVENT_LOGE("Update data from kvstore failed.");
100 dataManager_.CloseKvStore(appId_, kvStorePtr_);
101 kvStorePtr_ = nullptr;
102 return ERR_INVALID_OPERATION;
103 }
104 }
105
106 for (auto &disableEventsIt : disableEvents) {
107 DistributedKv::Key key(disableEventsIt.first);
108 DistributedKv::Value value = ConvertEventsToValue(disableEventsIt.second);
109 if (kvStorePtr_->Put(key, value) != DistributedKv::Status::SUCCESS) {
110 EVENT_LOGE("Update data from kvstore failed.");
111 dataManager_.CloseKvStore(appId_, kvStorePtr_);
112 kvStorePtr_ = nullptr;
113 return ERR_INVALID_OPERATION;
114 }
115 }
116
117 dataManager_.CloseKvStore(appId_, kvStorePtr_);
118 kvStorePtr_ = nullptr;
119 return ERR_OK;
120 }
121
QueryStaticSubscriberStateData(std::map<std::string,std::vector<std::string>> & disableEvents,std::set<std::string> & bundleList)122 int32_t StaticSubscriberDataManager::QueryStaticSubscriberStateData(
123 std::map<std::string, std::vector<std::string>> &disableEvents, std::set<std::string> &bundleList)
124
125 {
126 std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
127 if (!CheckKvStore()) {
128 EVENT_LOGE("Kvstore is nullptr.");
129 return ERR_NO_INIT;
130 }
131
132 std::vector<DistributedKv::Entry> allEntries;
133 if (kvStorePtr_->GetEntries(nullptr, allEntries) != DistributedKv::Status::SUCCESS) {
134 EVENT_LOGE("Get entries failed.");
135 return ERR_INVALID_OPERATION;
136 }
137
138 if (allEntries.empty()) {
139 dataManager_.CloseKvStore(appId_, kvStorePtr_);
140 kvStorePtr_ = nullptr;
141 EVENT_LOGD("The all entries is empty.");
142 return ERR_OK;
143 }
144
145 auto result = ERR_OK;
146 for (const auto &item : allEntries) {
147 if (item.value.ToString() == STATIC_SUBSCRIBER_VALUE_DEFAULT) {
148 bundleList.emplace(item.key.ToString());
149 } else {
150 std::vector<std::string> values;
151 if (!ConvertValueToEvents(item.value, values)) {
152 EVENT_LOGE("Failed to convert vector from value.");
153 result = ERR_INVALID_OPERATION;
154 break;
155 }
156 disableEvents.emplace(item.key.ToString(), values);
157 }
158 }
159
160 dataManager_.CloseKvStore(appId_, kvStorePtr_);
161 kvStorePtr_ = nullptr;
162 return result;
163 }
164
DeleteDisableEventElementByBundleName(const std::string & bundleName)165 int32_t StaticSubscriberDataManager::DeleteDisableEventElementByBundleName(const std::string &bundleName)
166 {
167 if (bundleName.empty()) {
168 EVENT_LOGE("Bundle name is invalid value.");
169 return ERR_INVALID_VALUE;
170 }
171
172 std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
173 if (!CheckKvStore()) {
174 EVENT_LOGE("Kvstore is nullptr.");
175 return ERR_NO_INIT;
176 }
177
178 EVENT_LOGD("Bundle name is %{public}s.", bundleName.c_str());
179 DistributedKv::Key key(bundleName);
180 if (kvStorePtr_->Delete(key) != DistributedKv::Status::SUCCESS) {
181 EVENT_LOGE("Delete data [%{public}s] from kvstore failed.", bundleName.c_str());
182 return ERR_INVALID_OPERATION;
183 }
184
185 dataManager_.CloseKvStore(appId_, kvStorePtr_);
186 kvStorePtr_ = nullptr;
187 return ERR_OK;
188 }
189
ConvertEventsToValue(const std::vector<std::string> & events)190 DistributedKv::Value StaticSubscriberDataManager::ConvertEventsToValue(const std::vector<std::string> &events)
191 {
192 nlohmann::json jsonNodes = nlohmann::json::array();
193 for (size_t index = 0; index < events.size(); index++) {
194 jsonNodes.emplace_back(events[index]);
195 }
196 return jsonNodes.dump();
197 }
198
ConvertValueToEvents(const DistributedKv::Value & value,std::vector<std::string> & events)199 bool StaticSubscriberDataManager::ConvertValueToEvents(
200 const DistributedKv::Value &value, std::vector<std::string> &events)
201 {
202 nlohmann::json jsonObject = nlohmann::json::parse(value.ToString(), nullptr, false);
203 if (jsonObject.is_null() || !jsonObject.is_array() || jsonObject.empty()) {
204 EVENT_LOGE("invalid common event obj size");
205 return false;
206 }
207 if (jsonObject.is_discarded()) {
208 EVENT_LOGE("Failed to parse json string.");
209 return false;
210 }
211 for (size_t index = 0; index < jsonObject.size(); index++) {
212 if (jsonObject[index].is_string()) {
213 events.emplace_back(jsonObject[index]);
214 }
215 }
216 return true;
217 }
218 } // namespace EventFwk
219 } // namespace OHOS
220