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