1 /*
2 * Copyright (c) 2021 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 #define LOG_TAG "KvStoreMetaManager"
16
17 #include "kvstore_meta_manager.h"
18
19 #include <chrono>
20 #include <condition_variable>
21 #include <directory_ex.h>
22 #include <file_ex.h>
23 #include <ipc_skeleton.h>
24 #include <thread>
25 #include <unistd.h>
26
27 #include "account_delegate.h"
28 #include "bootstrap.h"
29 #include "communication_provider.h"
30 #include "constant.h"
31 #include "crypto_manager.h"
32 #include "device_manager_adapter.h"
33 #include "device_matrix.h"
34 #include "directory_manager.h"
35 #include "dump_helper.h"
36 #include "eventcenter/event_center.h"
37 #include "kvstore_data_service.h"
38 #include "log_print.h"
39 #include "matrix_event.h"
40 #include "metadata/meta_data_manager.h"
41 #include "rdb_types.h"
42 #include "serializable/serializable.h"
43 #include "utils/anonymous.h"
44 #include "utils/crypto.h"
45
46 namespace OHOS {
47 namespace DistributedKv {
48 using json = nlohmann::json;
49 using Commu = AppDistributedKv::CommunicationProvider;
50 using DmAdapter = DistributedData::DeviceManagerAdapter;
51 using namespace std::chrono;
52 using namespace OHOS::DistributedData;
53 using namespace DistributedDB;
54
55 // APPID: distributeddata
56 // USERID: default
57 // STOREID: service_meta
58 // dataDir: /data/misc_de/0/mdds/Meta/${storeId}/sin_gen.db
59 KvStoreMetaManager::MetaDeviceChangeListenerImpl KvStoreMetaManager::listener_;
60
KvStoreMetaManager()61 KvStoreMetaManager::KvStoreMetaManager()
62 : metaDelegate_(nullptr), metaDBDirectory_(DirectoryManager::GetInstance().GetMetaStorePath()),
63 label_(Bootstrap::GetInstance().GetProcessLabel()),
64 delegateManager_(Bootstrap::GetInstance().GetProcessLabel(), "default")
65 {
66 ZLOGI("begin.");
67 }
68
~KvStoreMetaManager()69 KvStoreMetaManager::~KvStoreMetaManager()
70 {
71 }
72
GetInstance()73 KvStoreMetaManager &KvStoreMetaManager::GetInstance()
74 {
75 static KvStoreMetaManager instance;
76 return instance;
77 }
78
SubscribeMeta(const std::string & keyPrefix,const ChangeObserver & observer)79 void KvStoreMetaManager::SubscribeMeta(const std::string &keyPrefix, const ChangeObserver &observer)
80 {
81 metaObserver_.handlerMap_[keyPrefix] = observer;
82 }
83
InitMetaListener()84 void KvStoreMetaManager::InitMetaListener()
85 {
86 InitMetaData();
87 auto status = Commu::GetInstance().StartWatchDeviceChange(&listener_, { "metaMgr" });
88 if (status != AppDistributedKv::Status::SUCCESS) {
89 ZLOGW("register failed.");
90 return;
91 }
92 ZLOGI("register meta device change success.");
93 SubscribeMetaKvStore();
94 SyncMeta();
95 InitBroadcast();
96 InitDeviceOnline();
97 }
98
InitBroadcast()99 void KvStoreMetaManager::InitBroadcast()
100 {
101 auto pipe = Bootstrap::GetInstance().GetProcessLabel() + "-" + "default";
102 auto result = Commu::GetInstance().ListenBroadcastMsg({ pipe },
103 [](const std::string &device, uint16_t mask) { DeviceMatrix::GetInstance().OnBroadcast(device, mask); });
104
105 EventCenter::GetInstance().Subscribe(DeviceMatrix::MATRIX_BROADCAST, [pipe](const Event &event) {
106 auto &matrixEvent = static_cast<const MatrixEvent &>(event);
107 Commu::GetInstance().Broadcast({ pipe }, matrixEvent.GetMask());
108 });
109
110 ZLOGI("observer matrix broadcast %{public}d.", result);
111 }
112
InitDeviceOnline()113 void KvStoreMetaManager::InitDeviceOnline()
114 {
115 ZLOGI("observer matrix online event.");
116 EventCenter::GetInstance().Subscribe(DeviceMatrix::MATRIX_ONLINE, [this](const Event &event) {
117 const MatrixEvent &matrixEvent = static_cast<const MatrixEvent &>(event);
118 auto mask = matrixEvent.GetMask();
119 auto deviceId = matrixEvent.GetDeviceId();
120 auto store = GetMetaKvStore();
121 if (((mask & DeviceMatrix::META_STORE_MASK) != 0) && store != nullptr) {
122 auto onComplete = [deviceId, mask](const std::map<std::string, DBStatus> &) {
123 auto event = std::make_unique<MatrixEvent>(DeviceMatrix::MATRIX_META_FINISHED, deviceId, mask);
124 DeviceMatrix::GetInstance().OnExchanged(deviceId, DeviceMatrix::META_STORE_MASK);
125 EventCenter::GetInstance().PostEvent(std::move(event));
126 };
127 auto status = store->Sync({ deviceId }, DistributedDB::SyncMode::SYNC_MODE_PUSH_PULL, onComplete);
128 if (status == OK) {
129 return;
130 }
131 ZLOGW("meta db sync error %d.", status);
132 }
133
134 auto finEvent = std::make_unique<MatrixEvent>(DeviceMatrix::MATRIX_META_FINISHED, deviceId, mask);
135 EventCenter::GetInstance().PostEvent(std::move(finEvent));
136 });
137 }
138
InitMetaData()139 void KvStoreMetaManager::InitMetaData()
140 {
141 ZLOGI("start.");
142 auto metaDelegate = GetMetaKvStore();
143 if (metaDelegate == nullptr) {
144 ZLOGI("get meta failed.");
145 return;
146 }
147 auto uid = getuid();
148 const std::string accountId = AccountDelegate::GetInstance()->GetCurrentAccountId();
149 const std::string userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid);
150 StoreMetaData data;
151 data.appId = label_;
152 data.appType = "default";
153 data.bundleName = label_;
154 data.dataDir = metaDBDirectory_;
155 data.user = userId;
156 data.deviceId = Commu::GetInstance().GetLocalDevice().uuid;
157 data.isAutoSync = false;
158 data.isBackup = false;
159 data.isEncrypt = false;
160 data.storeType = KvStoreType::SINGLE_VERSION;
161 data.schema = "";
162 data.storeId = Constant::SERVICE_META_DB_NAME;
163 data.account = accountId;
164 data.uid = static_cast<int32_t>(uid);
165 data.version = META_STORE_VERSION;
166 data.securityLevel = SecurityLevel::S1;
167 data.area = EL1;
168 data.tokenId = IPCSkeleton::GetCallingTokenID();
169 if (!MetaDataManager::GetInstance().SaveMeta(data.GetKey(), data)) {
170 ZLOGE("save meta fail");
171 }
172
173 ZLOGI("end.");
174 }
175
InitMetaParameter()176 void KvStoreMetaManager::InitMetaParameter()
177 {
178 ZLOGI("start.");
179 std::thread th = std::thread([]() {
180 constexpr int RETRY_MAX_TIMES = 100;
181 int retryCount = 0;
182 constexpr int RETRY_TIME_INTERVAL_MILLISECOND = 1 * 1000 * 1000; // retry after 1 second
183 while (retryCount < RETRY_MAX_TIMES) {
184 auto status = CryptoManager::GetInstance().CheckRootKey();
185 if (status == CryptoManager::ErrCode::SUCCESS) {
186 ZLOGI("root key exist.");
187 break;
188 }
189 if (status == CryptoManager::ErrCode::NOT_EXIST &&
190 CryptoManager::GetInstance().GenerateRootKey() == CryptoManager::ErrCode::SUCCESS) {
191 ZLOGI("GenerateRootKey success.");
192 break;
193 }
194 retryCount++;
195 ZLOGE("GenerateRootKey failed.");
196 usleep(RETRY_TIME_INTERVAL_MILLISECOND);
197 }
198 });
199 th.detach();
200 DistributedDB::KvStoreConfig kvStoreConfig{ metaDBDirectory_ };
201 delegateManager_.SetKvStoreConfig(kvStoreConfig);
202 }
203
GetMetaKvStore()204 KvStoreMetaManager::NbDelegate KvStoreMetaManager::GetMetaKvStore()
205 {
206 if (metaDelegate_ != nullptr) {
207 return metaDelegate_;
208 }
209
210 std::lock_guard<decltype(mutex_)> lock(mutex_);
211 if (metaDelegate_ == nullptr) {
212 metaDelegate_ = CreateMetaKvStore();
213 }
214 ConfigMetaDataManager();
215 return metaDelegate_;
216 }
217
CreateMetaKvStore()218 KvStoreMetaManager::NbDelegate KvStoreMetaManager::CreateMetaKvStore()
219 {
220 DistributedDB::DBStatus dbStatusTmp = DistributedDB::DBStatus::NOT_SUPPORT;
221 DistributedDB::KvStoreNbDelegate::Option option;
222 option.createIfNecessary = true;
223 option.isMemoryDb = false;
224 option.createDirByStoreIdOnly = true;
225 option.isEncryptedDb = false;
226 option.isNeedRmCorruptedDb = true;
227 DistributedDB::KvStoreNbDelegate *delegate = nullptr;
228 delegateManager_.GetKvStore(Bootstrap::GetInstance().GetMetaDBName(), option,
229 [&delegate, &dbStatusTmp](DistributedDB::DBStatus dbStatus, DistributedDB::KvStoreNbDelegate *nbDelegate) {
230 delegate = nbDelegate;
231 dbStatusTmp = dbStatus;
232 });
233
234 if (dbStatusTmp != DistributedDB::DBStatus::OK) {
235 ZLOGE("GetKvStore return error status: %{public}d", static_cast<int>(dbStatusTmp));
236 return nullptr;
237 }
238 delegate->SetRemotePushFinishedNotify([](const RemotePushNotifyInfo &info) {
239 DeviceMatrix::GetInstance().OnExchanged(info.deviceId, DeviceMatrix::META_STORE_MASK);
240 });
241 auto release = [this](DistributedDB::KvStoreNbDelegate *delegate) {
242 ZLOGI("release meta data kv store");
243 if (delegate == nullptr) {
244 return;
245 }
246
247 auto result = delegateManager_.CloseKvStore(delegate);
248 if (result != DistributedDB::DBStatus::OK) {
249 ZLOGE("CloseMetaKvStore return error status: %{public}d", static_cast<int>(result));
250 }
251 };
252 return NbDelegate(delegate, release);
253 }
254
ConfigMetaDataManager()255 void KvStoreMetaManager::ConfigMetaDataManager()
256 {
257 auto fullName = GetBackupPath();
258 auto backup = [fullName](const auto &store) -> int32_t {
259 DistributedDB::CipherPassword password;
260 return store->Export(fullName, password);
261 };
262 auto syncer = [](const auto &store, int32_t status) {
263 ZLOGI("Syncer status: %{public}d", status);
264 DeviceMatrix::GetInstance().OnChanged(DeviceMatrix::META_STORE_MASK);
265 std::vector<std::string> devs;
266 auto devices = Commu::GetInstance().GetRemoteDevices();
267 for (auto const &dev : devices) {
268 devs.push_back(dev.uuid);
269 }
270
271 if (devs.empty()) {
272 ZLOGW("no devices need sync meta data.");
273 return;
274 }
275
276 status = store->Sync(devs, DistributedDB::SyncMode::SYNC_MODE_PUSH_PULL, [](auto &results) {
277 ZLOGD("meta data sync completed.");
278 for (auto &[uuid, status] : results) {
279 if (status != DistributedDB::OK) {
280 continue;
281 }
282 DeviceMatrix::GetInstance().OnExchanged(uuid, DeviceMatrix::META_STORE_MASK);
283 }
284 });
285
286 if (status != DistributedDB::OK) {
287 ZLOGW("meta data sync error %{public}d.", status);
288 }
289 };
290 MetaDataManager::GetInstance().Initialize(metaDelegate_, backup, syncer);
291 }
292
GetMetaKey(const std::string & deviceAccountId,const std::string & groupId,const std::string & bundleName,const std::string & storeId,const std::string & key)293 std::vector<uint8_t> KvStoreMetaManager::GetMetaKey(const std::string &deviceAccountId, const std::string &groupId,
294 const std::string &bundleName, const std::string &storeId, const std::string &key)
295 {
296 std::string originKey;
297 if (key.empty()) {
298 originKey = DmAdapter::GetInstance().GetLocalDevice().uuid + Constant::KEY_SEPARATOR + deviceAccountId +
299 Constant::KEY_SEPARATOR + groupId + Constant::KEY_SEPARATOR + bundleName +
300 Constant::KEY_SEPARATOR + storeId;
301 return KvStoreMetaRow::GetKeyFor(originKey);
302 }
303
304 originKey = deviceAccountId + Constant::KEY_SEPARATOR + groupId + Constant::KEY_SEPARATOR + bundleName +
305 Constant::KEY_SEPARATOR + storeId + Constant::KEY_SEPARATOR + key;
306 return SecretMetaRow::GetKeyFor(originKey);
307 }
308
SyncMeta()309 void KvStoreMetaManager::SyncMeta()
310 {
311 std::vector<std::string> devs;
312 auto deviceList = AppDistributedKv::CommunicationProvider::GetInstance().GetRemoteDevices();
313 for (auto const &dev : deviceList) {
314 devs.push_back(dev.uuid);
315 }
316
317 if (devs.empty()) {
318 ZLOGW("meta db sync fail, devices is empty.");
319 return;
320 }
321
322 auto metaDelegate = GetMetaKvStore();
323 if (metaDelegate == nullptr) {
324 ZLOGW("meta db sync failed.");
325 return;
326 }
327 auto onComplete = [this](const std::map<std::string, DistributedDB::DBStatus> &) {
328 ZLOGD("meta db sync complete end.");
329 };
330 auto dbStatus = metaDelegate->Sync(devs, DistributedDB::SyncMode::SYNC_MODE_PUSH_PULL, onComplete);
331 if (dbStatus != DistributedDB::OK) {
332 ZLOGW("meta db sync error %d.", dbStatus);
333 }
334 }
335
SubscribeMetaKvStore()336 void KvStoreMetaManager::SubscribeMetaKvStore()
337 {
338 auto metaDelegate = GetMetaKvStore();
339 if (metaDelegate == nullptr) {
340 ZLOGW("register meta observer failed.");
341 return;
342 }
343
344 int mode = DistributedDB::OBSERVER_CHANGES_NATIVE | DistributedDB::OBSERVER_CHANGES_FOREIGN;
345 auto dbStatus = metaDelegate->RegisterObserver(DistributedDB::Key(), mode, &metaObserver_);
346 if (dbStatus != DistributedDB::DBStatus::OK) {
347 ZLOGW("register meta observer failed :%{public}d.", dbStatus);
348 }
349 }
350
~KvStoreMetaObserver()351 KvStoreMetaManager::KvStoreMetaObserver::~KvStoreMetaObserver()
352 {
353 ZLOGW("meta observer destruct.");
354 }
355
OnChange(const DistributedDB::KvStoreChangedData & data)356 void KvStoreMetaManager::KvStoreMetaObserver::OnChange(const DistributedDB::KvStoreChangedData &data)
357 {
358 ZLOGD("on data change.");
359 HandleChanges(CHANGE_FLAG::INSERT, data.GetEntriesInserted());
360 HandleChanges(CHANGE_FLAG::UPDATE, data.GetEntriesUpdated());
361 HandleChanges(CHANGE_FLAG::DELETE, data.GetEntriesDeleted());
362 }
363
HandleChanges(CHANGE_FLAG flag,const std::list<DistributedDB::Entry> & entries)364 void KvStoreMetaManager::KvStoreMetaObserver::HandleChanges(CHANGE_FLAG flag,
365 const std::list<DistributedDB::Entry> &entries)
366 {
367 for (const auto &entry : entries) {
368 std::string key(entry.key.begin(), entry.key.end());
369 for (const auto &item : handlerMap_) {
370 ZLOGI("flag:%{public}d, key:%{public}s", flag, Anonymous::Change(key).c_str());
371 if (key.find(item.first) == 0) {
372 item.second(entry.key, entry.value, flag);
373 }
374 }
375 }
376 }
377
OnDeviceChanged(const AppDistributedKv::DeviceInfo & info,const AppDistributedKv::DeviceChangeType & type) const378 void KvStoreMetaManager::MetaDeviceChangeListenerImpl::OnDeviceChanged(const AppDistributedKv::DeviceInfo &info,
379 const AppDistributedKv::DeviceChangeType &type) const
380 {
381 EventCenter::Defer defer;
382 switch (type) {
383 case AppDistributedKv::DeviceChangeType::DEVICE_OFFLINE:
384 DeviceMatrix::GetInstance().Offline(info.uuid);
385 break;
386 case AppDistributedKv::DeviceChangeType::DEVICE_ONLINE:
387 DeviceMatrix::GetInstance().Online(info.uuid);
388 break;
389 default:
390 ZLOGI("flag:%{public}d", type);
391 break;
392 }
393 }
394
GetChangeLevelType() const395 AppDistributedKv::ChangeLevelType KvStoreMetaManager::MetaDeviceChangeListenerImpl::GetChangeLevelType() const
396 {
397 return AppDistributedKv::ChangeLevelType::LOW;
398 }
399
Marshal() const400 std::string KvStoreMetaData::Marshal() const
401 {
402 json jval = {
403 { DEVICE_ID, deviceId },
404 { USER_ID, userId },
405 { APP_ID, appId },
406 { STORE_ID, storeId },
407 { BUNDLE_NAME, bundleName },
408 { KVSTORE_TYPE, kvStoreType },
409 { ENCRYPT, isEncrypt },
410 { BACKUP, isBackup },
411 { AUTO_SYNC, isAutoSync },
412 { SCHEMA, schema },
413 { DATA_DIR, dataDir }, // Reserved for kvstore data storage directory.
414 { APP_TYPE, appType }, // Reserved for the APP type which used kvstore.
415 { DEVICE_ACCOUNT_ID, deviceAccountId },
416 { UID, uid },
417 { VERSION, version },
418 { SECURITY_LEVEL, securityLevel },
419 { DIRTY_KEY, isDirty },
420 { TOKEN_ID, tokenId },
421 };
422 return jval.dump();
423 }
424
ToJson(const std::string & jsonStr)425 json Serializable::ToJson(const std::string &jsonStr)
426 {
427 json jsonObj = json::parse(jsonStr, nullptr, false);
428 if (jsonObj.is_discarded()) {
429 // if the string size is less than 1, means the string is invalid.
430 if (jsonStr.empty()) {
431 ZLOGE("empty jsonStr, error.");
432 return {};
433 }
434 jsonObj = json::parse(jsonStr.substr(1), nullptr, false); // drop first char to adapt A's value;
435 if (jsonObj.is_discarded()) {
436 ZLOGE("parse jsonStr, error.");
437 return {};
438 }
439 }
440 return jsonObj;
441 }
442
Unmarshal(const nlohmann::json & jObject)443 void KvStoreMetaData::Unmarshal(const nlohmann::json &jObject)
444 {
445 kvStoreType = Serializable::GetVal<KvStoreType>(jObject, KVSTORE_TYPE, json::value_t::number_unsigned, kvStoreType);
446 isBackup = Serializable::GetVal<bool>(jObject, BACKUP, json::value_t::boolean, isBackup);
447 isEncrypt = Serializable::GetVal<bool>(jObject, ENCRYPT, json::value_t::boolean, isEncrypt);
448 isAutoSync = Serializable::GetVal<bool>(jObject, AUTO_SYNC, json::value_t::boolean, isAutoSync);
449 appId = Serializable::GetVal<std::string>(jObject, APP_ID, json::value_t::string, appId);
450 userId = Serializable::GetVal<std::string>(jObject, USER_ID, json::value_t::string, userId);
451 storeId = Serializable::GetVal<std::string>(jObject, STORE_ID, json::value_t::string, storeId);
452 bundleName = Serializable::GetVal<std::string>(jObject, BUNDLE_NAME, json::value_t::string, bundleName);
453 deviceAccountId =
454 Serializable::GetVal<std::string>(jObject, DEVICE_ACCOUNT_ID, json::value_t::string, deviceAccountId);
455 dataDir = Serializable::GetVal<std::string>(jObject, DATA_DIR, json::value_t::string, dataDir);
456 appType = Serializable::GetVal<std::string>(jObject, APP_TYPE, json::value_t::string, appType);
457 deviceId = Serializable::GetVal<std::string>(jObject, DEVICE_ID, json::value_t::string, deviceId);
458 schema = Serializable::GetVal<std::string>(jObject, SCHEMA, json::value_t::string, schema);
459 uid = Serializable::GetVal<int32_t>(jObject, UID, json::value_t::number_unsigned, uid);
460 version = Serializable::GetVal<uint32_t>(jObject, VERSION, json::value_t::number_unsigned, version);
461 securityLevel =
462 Serializable::GetVal<uint32_t>(jObject, SECURITY_LEVEL, json::value_t::number_unsigned, securityLevel);
463 isDirty = Serializable::GetVal<uint32_t>(jObject, DIRTY_KEY, json::value_t::boolean, isDirty);
464 tokenId = Serializable::GetVal<uint32_t>(jObject, TOKEN_ID, json::value_t::number_unsigned, tokenId);
465 }
466
467 template<typename T>
GetVal(const json & j,const std::string & name,json::value_t type,const T & val)468 T Serializable::GetVal(const json &j, const std::string &name, json::value_t type, const T &val)
469 {
470 auto it = j.find(name);
471 if (it != j.end() && it->type() == type) {
472 return *it;
473 }
474 ZLOGW("not found name:%s.", name.c_str());
475 return val;
476 }
477
Marshal() const478 std::vector<uint8_t> SecretKeyMetaData::Marshal() const
479 {
480 json jval = { { TIME, timeValue }, { SKEY, secretKey }, { KVSTORE_TYPE, kvStoreType } };
481 auto value = jval.dump();
482 return std::vector<uint8_t>(value.begin(), value.end());
483 }
484
Unmarshal(const nlohmann::json & jObject)485 void SecretKeyMetaData::Unmarshal(const nlohmann::json &jObject)
486 {
487 timeValue = Serializable::GetVal<std::vector<uint8_t>>(jObject, TIME, json::value_t::array, timeValue);
488 secretKey = Serializable::GetVal<std::vector<uint8_t>>(jObject, SKEY, json::value_t::array, secretKey);
489 kvStoreType = Serializable::GetVal<KvStoreType>(jObject, KVSTORE_TYPE, json::value_t::number_unsigned, kvStoreType);
490 }
491
GetFullMetaData(std::map<std::string,MetaData> & entries,enum DatabaseType type)492 bool KvStoreMetaManager::GetFullMetaData(std::map<std::string, MetaData> &entries, enum DatabaseType type)
493 {
494 ZLOGI("start");
495 auto metaDelegate = GetMetaKvStore();
496 if (metaDelegate == nullptr) {
497 return false;
498 }
499
500 std::vector<DistributedDB::Entry> kvStoreMetaEntries;
501 const std::string &metaKey = KvStoreMetaRow::KEY_PREFIX;
502 DistributedDB::DBStatus dbStatus = metaDelegate->GetEntries({ metaKey.begin(), metaKey.end() }, kvStoreMetaEntries);
503 if (dbStatus != DistributedDB::DBStatus::OK) {
504 ZLOGE("Get kvstore meta data entries from metaDB failed, dbStatus: %d.", static_cast<int>(dbStatus));
505 return false;
506 }
507
508 for (auto const &kvStoreMeta : kvStoreMetaEntries) {
509 std::string jsonStr(kvStoreMeta.value.begin(), kvStoreMeta.value.end());
510 ZLOGD("kvStoreMetaData get json: %s", jsonStr.c_str());
511 auto metaObj = Serializable::ToJson(jsonStr);
512 MetaData metaData{ 0 };
513 metaData.kvStoreType = MetaData::GetKvStoreType(metaObj);
514 if (!(type == KVDB && metaData.kvStoreType < KvStoreType::INVALID_TYPE) &&
515 !(type == RDB && metaData.kvStoreType >= DistributedRdb::RdbDistributedType::RDB_DEVICE_COLLABORATION)) {
516 continue;
517 }
518
519 metaData.kvStoreMetaData.Unmarshal(metaObj);
520 std::vector<uint8_t> decryptKey;
521 if (metaData.kvStoreMetaData.isEncrypt) {
522 ZLOGE("isEncrypt.");
523 const std::string keyType = ((metaData.kvStoreType == KvStoreType::SINGLE_VERSION) ? "SINGLE_KEY" : "KEY");
524 const std::vector<uint8_t> metaSecretKey =
525 KvStoreMetaManager::GetInstance().GetMetaKey(metaData.kvStoreMetaData.deviceAccountId, "default",
526 metaData.kvStoreMetaData.bundleName, metaData.kvStoreMetaData.storeId, keyType);
527 DistributedDB::Value secretValue;
528 metaDelegate->GetLocal(metaSecretKey, secretValue);
529 auto secretObj = Serializable::ToJson({ secretValue.begin(), secretValue.end() });
530 if (secretObj.empty()) {
531 ZLOGE("Failed to find SKEY in SecretKeyMetaData.");
532 continue;
533 }
534 metaData.secretKeyMetaData.Unmarshal(secretObj);
535 CryptoManager::GetInstance().Decrypt(metaData.secretKeyMetaData.secretKey, decryptKey);
536 }
537 entries.insert({ { kvStoreMeta.key.begin(), kvStoreMeta.key.end() }, { metaData } });
538 std::fill(decryptKey.begin(), decryptKey.end(), 0);
539 }
540
541 return true;
542 }
543
GetKvStoreMetaByType(const std::string & name,const std::string & val,KvStoreMetaData & metaData)544 bool KvStoreMetaManager::GetKvStoreMetaByType(const std::string &name, const std::string &val,
545 KvStoreMetaData &metaData)
546 {
547 auto metaDelegate = GetMetaKvStore();
548 if (metaDelegate == nullptr) {
549 return false;
550 }
551
552 DistributedDB::Key metaKeyPrefix = KvStoreMetaRow::GetKeyFor("");
553 std::vector<DistributedDB::Entry> metaEntries;
554 DistributedDB::DBStatus dbStatus = metaDelegate->GetEntries(metaKeyPrefix, metaEntries);
555 if (dbStatus != DistributedDB::DBStatus::OK) {
556 ZLOGE("Get meta entries from metaDB failed, dbStatus: %d.", static_cast<int>(dbStatus));
557 return false;
558 }
559
560 for (auto const &metaEntry : metaEntries) {
561 std::string jsonStr(metaEntry.value.begin(), metaEntry.value.end());
562 ZLOGD("KvStore get json: %s", jsonStr.c_str());
563 json jsonObj = json::parse(jsonStr, nullptr, false);
564 if (jsonObj.is_discarded()) {
565 ZLOGE("parse json error");
566 continue;
567 }
568
569 std::string metaTypeVal;
570 jsonObj[name].get_to(metaTypeVal);
571 if (metaTypeVal == val) {
572 metaData.Unmarshal(Serializable::ToJson(jsonStr));
573 }
574 }
575 return true;
576 }
577
GetKvStoreMetaDataByAppId(const std::string & appId,KvStoreMetaData & metaData)578 bool KvStoreMetaManager::GetKvStoreMetaDataByAppId(const std::string &appId, KvStoreMetaData &metaData)
579 {
580 return GetKvStoreMetaByType(KvStoreMetaData::APP_ID, appId, metaData);
581 }
582
GetBackupPath() const583 std::string KvStoreMetaManager::GetBackupPath() const
584 {
585 return (DirectoryManager::GetInstance().GetMetaBackupPath() + "/" +
586 Crypto::Sha256(label_ + "_" + Bootstrap::GetInstance().GetMetaDBName()));
587 }
588 } // namespace DistributedKv
589 } // namespace OHOS
590