1 /*
2 * Copyright (c) 2023 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
23 namespace OHOS {
24 namespace EventFwk {
25 namespace {
26 constexpr int32_t CHECK_INTERVAL = 100000; // 100ms
27 constexpr int32_t MAX_TIMES = 5; // 5 * 100ms = 500ms
28 constexpr const char *STATIC_SUBSCRIBER_STORAGE_DIR = "/data/service/el1/public/database/common_event_service";
29 const std::string STATIC_SUBSCRIBER_VALUE_DEFAULT = "0";
30 } // namespace
StaticSubscriberDataManager()31 StaticSubscriberDataManager::StaticSubscriberDataManager() {}
32
~StaticSubscriberDataManager()33 StaticSubscriberDataManager::~StaticSubscriberDataManager()
34 {
35 if (kvStorePtr_ != nullptr) {
36 dataManager_.CloseKvStore(appId_, kvStorePtr_);
37 }
38 }
39
GetKvStore()40 DistributedKv::Status StaticSubscriberDataManager::GetKvStore()
41 {
42 DistributedKv::Options options = {
43 .createIfMissing = true,
44 .encrypt = false,
45 .autoSync = false,
46 .syncable = false,
47 .area = DistributedKv::EL1,
48 .kvStoreType = DistributedKv::KvStoreType::SINGLE_VERSION,
49 .baseDir = STATIC_SUBSCRIBER_STORAGE_DIR
50 };
51
52 DistributedKv::Status status = dataManager_.GetSingleKvStore(options, appId_, storeId_, kvStorePtr_);
53 if (status != DistributedKv::Status::SUCCESS) {
54 EVENT_LOGE("return error: %{public}d", status);
55 }
56 return status;
57 }
58
CheckKvStore()59 bool StaticSubscriberDataManager::CheckKvStore()
60 {
61 if (kvStorePtr_ != nullptr) {
62 return true;
63 }
64 int32_t tryTimes = MAX_TIMES;
65 while (tryTimes > 0) {
66 DistributedKv::Status status = GetKvStore();
67 if (status == DistributedKv::Status::SUCCESS && kvStorePtr_ != nullptr) {
68 return true;
69 }
70 EVENT_LOGI("try times: %{public}d", tryTimes);
71 usleep(CHECK_INTERVAL);
72 tryTimes--;
73 }
74 return kvStorePtr_ != nullptr;
75 }
76
InsertDisableStaticSubscribeData(const std::string & bundleName)77 int32_t StaticSubscriberDataManager::InsertDisableStaticSubscribeData(const std::string &bundleName)
78 {
79 if (bundleName.empty()) {
80 EVENT_LOGW("invalid value!");
81 return ERR_INVALID_VALUE;
82 }
83 DistributedKv::Status status;
84 EVENT_LOGD("bundleName: %{public}s", bundleName.c_str());
85 {
86 std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
87 if (!CheckKvStore()) {
88 EVENT_LOGE("kvStore is nullptr");
89 return ERR_NO_INIT;
90 }
91 DistributedKv::Key key(bundleName);
92 DistributedKv::Value value(STATIC_SUBSCRIBER_VALUE_DEFAULT);
93 status = kvStorePtr_->Put(key, value);
94 }
95 int32_t result = ERR_OK;
96 if (status != DistributedKv::Status::SUCCESS) {
97 EVENT_LOGE("insert data [%{public}s] to kvStore failed. error code: %{public}d", bundleName.c_str(), status);
98 result = ERR_INVALID_OPERATION;
99 }
100
101 dataManager_.CloseKvStore(appId_, kvStorePtr_);
102 kvStorePtr_ = nullptr;
103
104 return result;
105 }
106
DeleteDisableStaticSubscribeData(const std::string & bundleName)107 int32_t StaticSubscriberDataManager::DeleteDisableStaticSubscribeData(const std::string &bundleName)
108 {
109 if (bundleName.empty()) {
110 EVENT_LOGW("invalid value!");
111 return ERR_INVALID_VALUE;
112 }
113 DistributedKv::Status status;
114 EVENT_LOGD("bundleName: %{public}s", bundleName.c_str());
115 {
116 std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
117 if (!CheckKvStore()) {
118 EVENT_LOGE("kvStore is nullptr");
119 return ERR_NO_INIT;
120 }
121 DistributedKv::Key key(bundleName);
122 status = kvStorePtr_->Delete(key);
123 }
124 int32_t result = ERR_OK;
125 if (status != DistributedKv::Status::SUCCESS) {
126 EVENT_LOGE("delete data [%{public}s] from kvStore failed. error code: %{public}d", bundleName.c_str(), status);
127 result = ERR_INVALID_OPERATION;
128 }
129
130 dataManager_.CloseKvStore(appId_, kvStorePtr_);
131 kvStorePtr_ = nullptr;
132
133 return result;
134 }
135
QueryDisableStaticSubscribeAllData(std::set<std::string> & disableStaticSubscribeAllData)136 int32_t StaticSubscriberDataManager::QueryDisableStaticSubscribeAllData(
137 std::set<std::string> &disableStaticSubscribeAllData)
138 {
139 {
140 std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
141 if (!CheckKvStore()) {
142 EVENT_LOGE("kvStore is nullptr");
143 return ERR_NO_INIT;
144 }
145 }
146
147 std::vector<DistributedKv::Entry> allEntries;
148 DistributedKv::Status status = kvStorePtr_->GetEntries(nullptr, allEntries);
149 int32_t result = ERR_OK;
150 if (status != DistributedKv::Status::SUCCESS) {
151 EVENT_LOGE("get entries failed, error code: %{public}d", status);
152 result = ERR_INVALID_OPERATION;
153 }
154
155 if (!allEntries.empty()) {
156 for (const auto &item : allEntries) {
157 disableStaticSubscribeAllData.emplace(item.key.ToString());
158 EVENT_LOGI("current disable static subscriber bundle name: %{public}s", item.key.ToString().c_str());
159 }
160 }
161
162 dataManager_.CloseKvStore(appId_, kvStorePtr_);
163 kvStorePtr_ = nullptr;
164
165 return result;
166 }
167 } // namespace EventFwk
168 } // namespace OHOS
169