1 /*
2 * Copyright (c) 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 "distributed_database.h"
17
18 #include "ans_log_wrapper.h"
19
20 namespace OHOS {
21 namespace Notification {
22 namespace {
23 const std::string APP_ID = "advanced_notification_service";
24 const std::string STORE_ID = "distributed_notification";
25 } // namespace
26
DistributedDatabase(std::shared_ptr<DistributedDatabaseCallback> databaseCb,std::shared_ptr<DistributedDeviceCallback> deviceCb)27 DistributedDatabase::DistributedDatabase(
28 std::shared_ptr<DistributedDatabaseCallback> databaseCb, std::shared_ptr<DistributedDeviceCallback> deviceCb)
29 : DistributedFlowControl(), databaseCb_(databaseCb), deviceCb_(deviceCb)
30 {
31 GetKvDataManager();
32 GetKvStore();
33 }
34
~DistributedDatabase()35 DistributedDatabase::~DistributedDatabase()
36 {}
37
GetKvDataManager(void)38 void DistributedDatabase::GetKvDataManager(void)
39 {
40 kvDataManager_ = std::make_unique<DistributedKv::DistributedKvDataManager>();
41 if (kvDataManager_ != nullptr) {
42 DistributedKv::Status status = kvDataManager_->StartWatchDeviceChange(deviceCb_);
43 if (status != DistributedKv::Status::SUCCESS) {
44 ANS_LOGW("kvDataManager StartWatchDeviceChange failed ret = 0x%{public}x", status);
45 kvDataManager_.reset();
46 }
47 }
48
49 KvManagerFlowControlClear();
50 }
51
CheckKvDataManager(void)52 bool DistributedDatabase::CheckKvDataManager(void)
53 {
54 if (kvDataManager_ == nullptr) {
55 GetKvDataManager();
56 }
57 if (kvDataManager_ == nullptr) {
58 ANS_LOGE("kvDataManager is nullptr.");
59 return false;
60 }
61 return true;
62 }
63
GetKvStore(void)64 void DistributedDatabase::GetKvStore(void)
65 {
66 if (!CheckKvDataManager()) {
67 return;
68 }
69
70 DistributedKv::Options options;
71 options.createIfMissing = true;
72 options.securityLevel = DistributedKv::SecurityLevel::S1;
73 options.autoSync = true;
74 options.kvStoreType = DistributedKv::KvStoreType::SINGLE_VERSION;
75 DistributedKv::AppId appId = {.appId = APP_ID};
76 DistributedKv::StoreId storeId = {.storeId = STORE_ID};
77 DistributedKv::Status status = kvDataManager_->GetSingleKvStore(options, appId, storeId, kvStore_);
78 if (status != DistributedKv::Status::SUCCESS) {
79 ANS_LOGE("kvDataManager GetSingleKvStore failed ret = 0x%{public}x", status);
80 kvStore_.reset();
81 kvDataManager_->StopWatchDeviceChange(deviceCb_);
82 kvDataManager_.reset();
83 return;
84 }
85
86 if (kvStore_ != nullptr) {
87 status = kvStore_->SubscribeKvStore(DistributedKv::SubscribeType::SUBSCRIBE_TYPE_REMOTE, databaseCb_);
88 if (status != DistributedKv::Status::SUCCESS) {
89 ANS_LOGE("kvStore SubscribeKvStore failed ret = 0x%{public}x", status);
90 kvStore_.reset();
91 }
92 }
93
94 KvStoreFlowControlClear();
95 }
96
CheckKvStore(void)97 bool DistributedDatabase::CheckKvStore(void)
98 {
99 if (kvStore_ == nullptr) {
100 GetKvStore();
101 }
102 if (kvStore_ == nullptr) {
103 ANS_LOGE("kvStore is nullptr.");
104 return false;
105 }
106 return true;
107 }
108
PutToDistributedDB(const std::string & key,const std::string & value)109 bool DistributedDatabase::PutToDistributedDB(const std::string &key, const std::string &value)
110 {
111 std::lock_guard<std::mutex> lock(mutex_);
112
113 if (!CheckKvStore()) {
114 return false;
115 }
116
117 if (!KvStoreFlowControl()) {
118 ANS_LOGE("KvStore flow control.");
119 return false;
120 }
121
122 DistributedKv::Key kvStoreKey(key);
123 DistributedKv::Value kvStoreValue(value);
124 DistributedKv::Status status = kvStore_->Put(kvStoreKey, kvStoreValue);
125 if (status != DistributedKv::Status::SUCCESS) {
126 ANS_LOGE("kvStore Put() failed ret = 0x%{public}x", status);
127 return false;
128 }
129
130 return true;
131 }
132
GetFromDistributedDB(const std::string & key,std::string & value)133 bool DistributedDatabase::GetFromDistributedDB(const std::string &key, std::string &value)
134 {
135 std::lock_guard<std::mutex> lock(mutex_);
136
137 if (!CheckKvStore()) {
138 return false;
139 }
140
141 if (!KvStoreFlowControl()) {
142 ANS_LOGE("KvStore flow control.");
143 return false;
144 }
145
146 DistributedKv::Key kvStoreKey(key);
147 DistributedKv::Value kvStoreValue;
148 DistributedKv::Status status = kvStore_->Get(kvStoreKey, kvStoreValue);
149 if (status != DistributedKv::Status::SUCCESS) {
150 ANS_LOGE("kvStore Get() failed ret = 0x%{public}x", status);
151 return false;
152 }
153
154 value = kvStoreValue.ToString();
155
156 return true;
157 }
158
GetEntriesFromDistributedDB(const std::string & prefixKey,std::vector<Entry> & entries)159 bool DistributedDatabase::GetEntriesFromDistributedDB(const std::string &prefixKey, std::vector<Entry> &entries)
160 {
161 std::lock_guard<std::mutex> lock(mutex_);
162
163 if (!CheckKvStore()) {
164 return false;
165 }
166
167 if (!KvStoreFlowControl()) {
168 ANS_LOGE("KvStore flow control.");
169 return false;
170 }
171
172 DistributedKv::Key kvStoreKey(prefixKey);
173 DistributedKv::Status status = kvStore_->GetEntries(kvStoreKey, entries);
174 if (status != DistributedKv::Status::SUCCESS) {
175 ANS_LOGE("kvStore GetEntries() failed ret = 0x%{public}x", status);
176 return false;
177 }
178
179 return true;
180 }
181
DeleteToDistributedDB(const std::string & key)182 bool DistributedDatabase::DeleteToDistributedDB(const std::string &key)
183 {
184 std::lock_guard<std::mutex> lock(mutex_);
185
186 if (!CheckKvStore()) {
187 return false;
188 }
189
190 if (!KvStoreFlowControl()) {
191 ANS_LOGE("KvStore flow control.");
192 return false;
193 }
194
195 DistributedKv::Key kvStoreKey(key);
196 DistributedKv::Status status = kvStore_->Delete(kvStoreKey);
197 if (status != DistributedKv::Status::SUCCESS) {
198 ANS_LOGE("kvStore Delete() failed ret = 0x%{public}x", status);
199 return false;
200 }
201
202 return true;
203 }
204
ClearDataByDevice(const std::string & deviceId)205 bool DistributedDatabase::ClearDataByDevice(const std::string &deviceId)
206 {
207 std::lock_guard<std::mutex> lock(mutex_);
208
209 if (!CheckKvStore()) {
210 return false;
211 }
212
213 if (!KvStoreFlowControl()) {
214 ANS_LOGE("KvStore flow control.");
215 return false;
216 }
217
218 DistributedKv::Status status = kvStore_->RemoveDeviceData(deviceId);
219 if (status != DistributedKv::Status::SUCCESS) {
220 ANS_LOGE("kvStore RemoveDeviceData() failed ret = 0x%{public}x", status);
221 return false;
222 }
223
224 return true;
225 }
226
GetLocalDeviceId(std::string & deviceId)227 bool DistributedDatabase::GetLocalDeviceId(std::string &deviceId)
228 {
229 std::lock_guard<std::mutex> lock(mutex_);
230 if (!CheckKvDataManager()) {
231 return false;
232 }
233
234 if (KvManagerFlowControl()) {
235 DistributedKv::DeviceInfo deviceInfo;
236 DistributedKv::Status status = kvDataManager_->GetLocalDevice(deviceInfo);
237 if (status != DistributedKv::Status::SUCCESS) {
238 ANS_LOGE("kvDataManager GetLocalDevice() failed ret = 0x%{public}x", status);
239 return false;
240 }
241
242 localDeviceId_ = deviceInfo.deviceId;
243 }
244
245 if (localDeviceId_.empty()) {
246 return false;
247 }
248
249 deviceId = localDeviceId_;
250
251 return true;
252 }
253
GetLocalDeviceInfo(DeviceInfo & localInfo)254 bool DistributedDatabase::GetLocalDeviceInfo(DeviceInfo &localInfo)
255 {
256 std::lock_guard<std::mutex> lock(mutex_);
257 if (!CheckKvDataManager()) {
258 return false;
259 }
260
261 if (!KvManagerFlowControl()) {
262 ANS_LOGE("KvManager flow control.");
263 return false;
264 }
265
266 DistributedKv::Status status = kvDataManager_->GetLocalDevice(localInfo);
267 if (status != DistributedKv::Status::SUCCESS) {
268 ANS_LOGE("kvDataManager GetLocalDevice() failed ret = 0x%{public}x", status);
269 return false;
270 }
271
272 return true;
273 }
274
GetDeviceInfoList(std::vector<DeviceInfo> & deviceList)275 bool DistributedDatabase::GetDeviceInfoList(std::vector<DeviceInfo> &deviceList)
276 {
277 std::lock_guard<std::mutex> lock(mutex_);
278 if (!CheckKvDataManager()) {
279 return false;
280 }
281
282 if (!KvManagerFlowControl()) {
283 ANS_LOGE("KvManager flow control.");
284 return false;
285 }
286
287 DistributedKv::Status status =
288 kvDataManager_->GetDeviceList(deviceList, DistributedKv::DeviceFilterStrategy::NO_FILTER);
289 if (status != DistributedKv::Status::SUCCESS) {
290 ANS_LOGE("kvDataManager GetDeviceList() failed ret = 0x%{public}x", status);
291 return false;
292 }
293
294 return true;
295 }
296
RecreateDistributedDB()297 bool DistributedDatabase::RecreateDistributedDB()
298 {
299 std::lock_guard<std::mutex> lock(mutex_);
300 if (!CheckKvDataManager()) {
301 return false;
302 }
303
304 if (!KvManagerFlowControl()) {
305 ANS_LOGE("KvManager flow control.");
306 return false;
307 }
308
309 kvStore_.reset();
310
311 DistributedKv::AppId appId = {.appId = APP_ID};
312 DistributedKv::StoreId storeId = {.storeId = STORE_ID};
313 DistributedKv::Status status = kvDataManager_->DeleteKvStore(appId, storeId);
314 if (status != DistributedKv::Status::SUCCESS) {
315 ANS_LOGE("kvDataManager DeleteKvStore() failed ret = 0x%{public}x", status);
316 return false;
317 }
318
319 GetKvStore();
320 return true;
321 }
322 } // namespace Notification
323 } // namespace OHOS