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