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