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 22namespace OHOS { 23namespace Notification { 24namespace { 25const std::string APP_ID = "notification_service"; 26const std::string STORE_ID = "distributed_notification"; 27constexpr char KV_STORE_PATH[] = "/data/service/el1/public/database/notification_service"; 28} // namespace 29 30DistributedDatabase::DistributedDatabase( 31 std::shared_ptr<DistributedDatabaseCallback> databaseCb, std::shared_ptr<DistributedDeviceCallback> deviceCb) 32 : DistributedFlowControl(), databaseCb_(databaseCb), deviceCb_(deviceCb) 33{ 34 GetKvDataManager(); 35} 36 37DistributedDatabase::~DistributedDatabase() 38{} 39 40void 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 58void DistributedDatabase::DeviceInitCallBack::OnRemoteDied() 59{ 60 ANS_LOGW("DeviceInitCallBack OnRemoteDied"); 61} 62 63bool 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 75void 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 119bool 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 132bool DistributedDatabase::OnDeviceConnected() 133{ 134 return CheckKvStore(); 135} 136 137bool 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 162bool 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 189bool 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 213bool 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 237bool 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 260bool 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 286bool 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 307bool 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 328bool 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