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