• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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