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