• 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 <ipc_skeleton.h>
20 #include <thread>
21 #include <unistd.h>
22 
23 #include "account/account_delegate.h"
24 #include "bootstrap.h"
25 #include "communication_provider.h"
26 #include "crypto/crypto_manager.h"
27 #include "device_manager_adapter.h"
28 #include "device_matrix.h"
29 #include "directory/directory_manager.h"
30 #include "eventcenter/event_center.h"
31 #include "kvstore_data_service.h"
32 #include "kv_radar_reporter.h"
33 #include "log_print.h"
34 #include "matrix_event.h"
35 #include "metadata/auto_launch_meta_data.h"
36 #include "metadata/capability_meta_data.h"
37 #include "metadata/device_meta_data.h"
38 #include "metadata/meta_data_manager.h"
39 #include "metadata/matrix_meta_data.h"
40 #include "metadata/strategy_meta_data.h"
41 #include "metadata/store_meta_data_local.h"
42 #include "metadata/strategy_meta_data.h"
43 #include "metadata/switches_meta_data.h"
44 #include "metadata/user_meta_data.h"
45 #include "metadata/version_meta_data.h"
46 #include "runtime_config.h"
47 #include "safe_block_queue.h"
48 #include "store/general_store.h"
49 #include "store/store_info.h"
50 #include "utils/anonymous.h"
51 #include "utils/block_integer.h"
52 #include "utils/corrupt_reporter.h"
53 #include "utils/crypto.h"
54 #include "utils/ref_count.h"
55 #include "utils/converter.h"
56 #include "utils/constant.h"
57 
58 namespace OHOS {
59 namespace DistributedKv {
60 using Commu = AppDistributedKv::CommunicationProvider;
61 using DmAdapter = DistributedData::DeviceManagerAdapter;
62 using namespace std::chrono;
63 using namespace OHOS::DistributedData;
64 using namespace DistributedDB;
65 using namespace OHOS::AppDistributedKv;
66 
67 KvStoreMetaManager::MetaDeviceChangeListenerImpl KvStoreMetaManager::listener_;
68 KvStoreMetaManager::DBInfoDeviceChangeListenerImpl KvStoreMetaManager::dbInfoListener_;
69 
KvStoreMetaManager()70 KvStoreMetaManager::KvStoreMetaManager()
71     : metaDelegate_(nullptr), metaDBDirectory_(DirectoryManager::GetInstance().GetMetaStorePath()),
72       label_(Bootstrap::GetInstance().GetProcessLabel()),
73       delegateManager_(Bootstrap::GetInstance().GetProcessLabel(), "default")
74 {
75     ZLOGI("begin.");
76 }
77 
~KvStoreMetaManager()78 KvStoreMetaManager::~KvStoreMetaManager()
79 {
80     if (delaySyncTaskId_ != ExecutorPool::INVALID_TASK_ID) {
81         executors_->Remove(delaySyncTaskId_);
82         delaySyncTaskId_ = ExecutorPool::INVALID_TASK_ID;
83     }
84 }
85 
GetInstance()86 KvStoreMetaManager &KvStoreMetaManager::GetInstance()
87 {
88     static KvStoreMetaManager instance;
89     return instance;
90 }
91 
SubscribeMeta(const std::string & keyPrefix,const ChangeObserver & observer)92 void KvStoreMetaManager::SubscribeMeta(const std::string &keyPrefix, const ChangeObserver &observer)
93 {
94     metaObserver_.handlerMap_[keyPrefix] = observer;
95 }
96 
InitMetaListener()97 void KvStoreMetaManager::InitMetaListener()
98 {
99     InitMetaData();
100     auto status = DmAdapter::GetInstance().StartWatchDeviceChange(&listener_, { "metaMgr" });
101     if (status != AppDistributedKv::Status::SUCCESS) {
102         ZLOGW("register metaMgr failed: %{public}d.", status);
103         return;
104     }
105     SubscribeMetaKvStore();
106     InitBroadcast();
107     NotifyAllAutoSyncDBInfo();
108 }
109 
InitBroadcast()110 void KvStoreMetaManager::InitBroadcast()
111 {
112     auto pipe = Bootstrap::GetInstance().GetProcessLabel() + "-" + "default";
113     auto result = Commu::GetInstance().ListenBroadcastMsg({ pipe },
114         [](const std::string &device, const AppDistributedKv::LevelInfo &levelInfo) {
115             DistributedData::DeviceMatrix::DataLevel level;
116             level.dynamic = levelInfo.dynamic;
117             level.statics = levelInfo.statics;
118             level.switches = levelInfo.switches;
119             level.switchesLen = levelInfo.switchesLen;
120             DeviceMatrix::GetInstance().OnBroadcast(device, std::move(level));
121         });
122 
123     EventCenter::GetInstance().Subscribe(DeviceMatrix::MATRIX_BROADCAST, [pipe](const Event &event) {
124         auto &matrixEvent = static_cast<const MatrixEvent &>(event);
125         auto matrixData = matrixEvent.GetMatrixData();
126         AppDistributedKv::LevelInfo level;
127         level.dynamic = matrixData.dynamic;
128         level.statics = matrixData.statics;
129         level.switches = matrixData.switches;
130         level.switchesLen = matrixData.switchesLen;
131         Commu::GetInstance().Broadcast({ pipe }, std::move(level));
132     });
133 
134     ZLOGI("observer matrix broadcast %{public}d.", result);
135 }
136 
InitMetaData()137 void KvStoreMetaManager::InitMetaData()
138 {
139     ZLOGI("start.");
140     auto metaDelegate = GetMetaKvStore();
141     if (metaDelegate == nullptr) {
142         ZLOGI("get meta failed.");
143         return;
144     }
145 
146     StoreMetaData data = InitStoreMetaData();
147     StoreMetaDataLocal localData;
148     localData.isAutoSync = false;
149     localData.isBackup = false;
150     localData.isEncrypt = false;
151     localData.dataDir = metaDBDirectory_;
152     localData.schema = "";
153     localData.isPublic = true;
154     MetaDataManager::GetInstance().SaveMeta(data.GetKeyWithoutPath(), data);
155     MetaDataManager::GetInstance().SaveMeta(data.GetKey(), data, true);
156     MetaDataManager::GetInstance().SaveMeta(data.GetKeyLocal(), localData, true);
157     std::string localUuid;
158     DeviceMetaData deviceMeta;
159     if (MetaDataManager::GetInstance().LoadMeta(deviceMeta.GetKey(), deviceMeta, true)) {
160         localUuid = deviceMeta.newUuid;
161     } else {
162         localUuid = DmAdapter::GetInstance().GetLocalDevice().uuid;
163     }
164     if (localUuid.empty()) {
165         ZLOGE("get uuid failed");
166         return;
167     }
168     UpdateMetaData(localUuid);
169     CheckMetaDeviceId();
170     SetCloudSyncer();
171     ZLOGI("end.");
172 }
173 
InitStoreMetaData()174 StoreMetaData KvStoreMetaManager::InitStoreMetaData()
175 {
176     StoreMetaData data;
177     auto uid = getuid();
178     auto tokenId = IPCSkeleton::GetCallingTokenID();
179     auto userId = AccountDelegate::GetInstance()->GetUserByToken(tokenId);
180     data.appId = label_;
181     data.appType = "default";
182     data.bundleName = label_;
183     data.dataDir = metaDBDirectory_;
184     data.user = std::to_string(userId);
185     data.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
186     data.isAutoSync = false;
187     data.isBackup = false;
188     data.isEncrypt = false;
189     data.isNeedCompress = true;
190     data.storeType = KvStoreType::SINGLE_VERSION;
191     data.dataType = DataType::TYPE_DYNAMICAL;
192     data.schema = "";
193     data.storeId = Bootstrap::GetInstance().GetMetaDBName();
194     data.account = AccountDelegate::GetInstance()->GetCurrentAccountId();
195     data.uid = static_cast<int32_t>(uid);
196     data.version = META_STORE_VERSION;
197     data.securityLevel = SecurityLevel::S1;
198     data.area = EL1;
199     data.tokenId = tokenId;
200     return data;
201 }
202 
UpdateMetaData(const std::string & uuid)203 void KvStoreMetaManager::UpdateMetaData(const std::string &uuid)
204 {
205     VersionMetaData versionMeta;
206     bool isExist = MetaDataManager::GetInstance().LoadMeta(versionMeta.GetKey(), versionMeta, true);
207     if (isExist && versionMeta.version == VersionMetaData::CURRENT_VERSION) {
208         return;
209     }
210     bool syncMetaUpdateNeeded = !isExist || versionMeta.version < VersionMetaData::UPDATE_SYNC_META_VERSION;
211     bool storeMetaUpgradeNeeded = !isExist || versionMeta.version < VersionMetaData::UPDATE_STORE_META_KEY_VERSION;
212     if (syncMetaUpdateNeeded) {
213         std::vector<StoreMetaData> metaDataList;
214         std::string prefix = StoreMetaData::GetPrefix({ uuid });
215         MetaDataManager::GetInstance().LoadMeta(prefix, metaDataList);
216         std::vector<std::string> keys;
217         for (const auto &metaData : metaDataList) {
218             MetaDataManager::GetInstance().SaveMeta(metaData.GetKey(), metaData, true);
219             if (CheckerManager::GetInstance().IsDistrust(Converter::ConvertToStoreInfo(metaData)) ||
220                 (metaData.storeType >= StoreMetaData::StoreType::STORE_RELATIONAL_BEGIN &&
221                     metaData.storeType <= StoreMetaData::StoreType::STORE_RELATIONAL_END)) {
222                 keys.push_back(metaData.GetKey());
223             }
224         }
225         MetaDataManager::GetInstance().DelMeta(keys);
226         versionMeta.version = VersionMetaData::UPDATE_SYNC_META_VERSION;
227         MetaDataManager::GetInstance().SaveMeta(versionMeta.GetKey(), versionMeta, true);
228     }
229     if (storeMetaUpgradeNeeded && UpgradeStoreMeta(uuid)) {
230         versionMeta.version = VersionMetaData::UPDATE_STORE_META_KEY_VERSION;
231         MetaDataManager::GetInstance().SaveMeta(versionMeta.GetKey(), versionMeta, true);
232     }
233 }
234 
235 // The metadata database is upgraded. The suffix is added to the path.
UpgradeStoreMeta(const std::string & uuid)236 bool KvStoreMetaManager::UpgradeStoreMeta(const std::string &uuid)
237 {
238     std::vector<StoreMetaData> metaDataList;
239     std::string prefix = StoreMetaData::GetPrefix({ uuid });
240     if (!MetaDataManager::GetInstance().LoadMeta(prefix, metaDataList, true)) {
241         ZLOGE("load meta failed");
242         return false;
243     }
244     size_t batchSize = 100; // The batch quantity is 100.
245     return Constant::BatchProcess(metaDataList, batchSize, [](const auto &begin, const auto &end) {
246         std::vector<MetaDataManager::Entry> entries;
247         std::vector<std::string> deleteKeys;
248         auto size = static_cast<size_t>(std::distance(begin, end));
249         entries.reserve(size * 3); // Expand the entries size by 3 times.
250         deleteKeys.reserve(size * 4); // Expand the deleteKeys size by 4 times.
251         auto it = begin;
252         do {
253             auto &meta = *it;
254             StoreMetaDataLocal localMeta;
255             bool isExist = MetaDataManager::GetInstance().LoadMeta(meta.GetKeyLocalWithoutPath(), localMeta, true);
256             if (isExist) {
257                 deleteKeys.push_back(meta.GetKeyLocalWithoutPath());
258                 entries.push_back({ meta.GetKeyLocal(), Serializable::Marshall(localMeta) });
259             }
260             SecretKeyMetaData secretKeyMetaData;
261             isExist = MetaDataManager::GetInstance().LoadMeta(meta.GetSecretKeyWithoutPath(), secretKeyMetaData, true);
262             if (isExist) {
263                 deleteKeys.push_back(meta.GetSecretKeyWithoutPath());
264                 entries.push_back({ meta.GetSecretKey(), Serializable::Marshall(secretKeyMetaData) });
265             }
266             deleteKeys.push_back(meta.GetKeyWithoutPath());
267             deleteKeys.push_back(meta.GetDebugInfoKeyWithoutPath());
268             deleteKeys.push_back(meta.GetDfxInfoKeyWithoutPath());
269             StoreMetaMapping storeMetaMapping(meta);
270             auto key = storeMetaMapping.GetKey();
271             entries.push_back({ std::move(key), Serializable::Marshall(storeMetaMapping) });
272             entries.push_back({ meta.GetKey(), Serializable::Marshall(meta) });
273         } while (++it != end);
274 
275         if (MetaDataManager::GetInstance().SaveMeta(entries, true)) {
276             MetaDataManager::GetInstance().DelMeta(deleteKeys, true);
277             return true;
278         }
279         return false;
280     });
281 }
282 
InitMetaParameter()283 void KvStoreMetaManager::InitMetaParameter()
284 {
285     ZLOGI("start.");
286     executors_->Execute(GetTask(0));
287     DistributedDB::KvStoreConfig kvStoreConfig{ metaDBDirectory_ };
288     delegateManager_.SetKvStoreConfig(kvStoreConfig);
289 }
290 
GetTask(uint32_t retry)291 ExecutorPool::Task KvStoreMetaManager::GetTask(uint32_t retry)
292 {
293     return [this, retry] {
294         auto status = CryptoManager::GetInstance().CheckRootKey();
295         if (status == CryptoManager::ErrCode::SUCCESS) {
296             ZLOGI("root key exist.");
297             return;
298         }
299         if (status == CryptoManager::ErrCode::NOT_EXIST &&
300             CryptoManager::GetInstance().GenerateRootKey() == CryptoManager::ErrCode::SUCCESS) {
301             ZLOGI("GenerateRootKey success.");
302             return;
303         }
304         ZLOGW("GenerateRootKey failed, retry times:%{public}d.", static_cast<int>(retry));
305         if (retry + 1 > RETRY_MAX_TIMES) {
306             ZLOGE("fail to register subscriber!");
307             return;
308         }
309         executors_->Schedule(std::chrono::seconds(RETRY_INTERVAL), GetTask(retry + 1));
310     };
311 }
312 
GetMetaKvStore()313 KvStoreMetaManager::NbDelegate KvStoreMetaManager::GetMetaKvStore()
314 {
315     if (metaDelegate_ != nullptr) {
316         return metaDelegate_;
317     }
318     std::lock_guard<decltype(mutex_)> lock(mutex_);
319     if (metaDelegate_ != nullptr) {
320         return metaDelegate_;
321     }
322 
323     auto metaDbName = Bootstrap::GetInstance().GetMetaDBName();
324     if (CorruptReporter::HasCorruptedFlag(metaDBDirectory_, metaDbName)) {
325         DistributedDB::DBStatus dbStatus = delegateManager_.DeleteKvStore(metaDbName);
326         if (dbStatus != DistributedDB::DBStatus::OK) {
327             ZLOGE("delete meta store failed! dbStatus: %{public}d", dbStatus);
328         }
329         metaDelegate_ = CreateMetaKvStore(true);
330         if (metaDelegate_ != nullptr) {
331             CorruptReporter::DeleteCorruptedFlag(metaDBDirectory_, metaDbName);
332         }
333     } else {
334         metaDelegate_ = CreateMetaKvStore();
335     }
336     auto fullName = GetBackupPath();
337     auto backup = [executors = executors_, queue = std::make_shared<SafeBlockQueue<Backup>>(MAX_TASK_COUNT), fullName](
338                       const auto &store) -> int32_t {
339         auto result = queue->PushNoWait([fullName](const auto &store) -> int32_t {
340             auto dbStatus = store->CheckIntegrity();
341             if (dbStatus != DistributedDB::DBStatus::OK) {
342                 ZLOGE("meta store check integrity fail, dbStatus:%{public}d", dbStatus);
343                 return dbStatus;
344             }
345             return store->Export(fullName, {}, true);
346         });
347         if (!result) {
348             return OK;
349         }
350         executors->Schedule(std::chrono::hours(RETRY_INTERVAL), GetBackupTask(queue, executors, store));
351         return OK;
352     };
353     MetaDataManager::GetInstance().Initialize(metaDelegate_, backup, metaDbName);
354     return metaDelegate_;
355 }
356 
GetBackupTask(TaskQueue queue,std::shared_ptr<ExecutorPool> executors,const NbDelegate store)357 ExecutorPool::Task KvStoreMetaManager::GetBackupTask(
358     TaskQueue queue, std::shared_ptr<ExecutorPool> executors, const NbDelegate store)
359 {
360     return [queue, executors, store]() {
361         Backup backupTask;
362         if (!queue->PopNotWait(backupTask)) {
363             return;
364         }
365         if (backupTask(store) != OK && queue->PushNoWait(backupTask)) {
366             executors->Schedule(std::chrono::hours(RETRY_INTERVAL), GetBackupTask(queue, executors, store));
367         }
368     };
369 }
370 
CreateMetaKvStore(bool isRestore)371 KvStoreMetaManager::NbDelegate KvStoreMetaManager::CreateMetaKvStore(bool isRestore)
372 {
373     DistributedDB::DBStatus dbStatusTmp = DistributedDB::DBStatus::NOT_SUPPORT;
374     auto option = InitDBOption();
375     DistributedDB::KvStoreNbDelegate *delegate = nullptr;
376     if (!isRestore) {
377         delegateManager_.GetKvStore(Bootstrap::GetInstance().GetMetaDBName(), option,
378             [&delegate, &dbStatusTmp](DistributedDB::DBStatus dbStatus, DistributedDB::KvStoreNbDelegate *nbDelegate) {
379                 delegate = nbDelegate;
380                 dbStatusTmp = dbStatus;
381             });
382     }
383     if (dbStatusTmp == DistributedDB::DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB || isRestore) {
384         ZLOGE("meta data corrupted!");
385         option.isNeedRmCorruptedDb = true;
386         auto fullName = GetBackupPath();
387         delegateManager_.GetKvStore(Bootstrap::GetInstance().GetMetaDBName(), option,
388             [&delegate, &dbStatusTmp, &fullName](DistributedDB::DBStatus dbStatus,
389                 DistributedDB::KvStoreNbDelegate *nbDelegate) {
390                 delegate = nbDelegate;
391                 dbStatusTmp = dbStatus;
392                 if (dbStatusTmp == DistributedDB::DBStatus::OK && delegate != nullptr) {
393                     ZLOGI("start import meta data");
394                     DistributedDB::CipherPassword password;
395                     delegate->Import(fullName, password, true);
396                 }
397             });
398     }
399     if (dbStatusTmp != DistributedDB::DBStatus::OK || delegate == nullptr) {
400         ZLOGE("GetKvStore return error status: %{public}d or delegate is nullptr", static_cast<int>(dbStatusTmp));
401         return nullptr;
402     }
403     delegate->SetRemotePushFinishedNotify([](const RemotePushNotifyInfo &info) {
404         DeviceMatrix::GetInstance().OnExchanged(info.deviceId, DeviceMatrix::META_STORE_MASK,
405             DeviceMatrix::LevelType::DYNAMIC, DeviceMatrix::ChangeType::CHANGE_REMOTE);
406     });
407     bool param = true;
408     auto data = static_cast<DistributedDB::PragmaData>(&param);
409     delegate->Pragma(DistributedDB::SET_SYNC_RETRY, data);
410     auto release = [this](DistributedDB::KvStoreNbDelegate *delegate) {
411         ZLOGI("release meta data kv store");
412         if (delegate == nullptr) {
413             return;
414         }
415         auto result = delegateManager_.CloseKvStore(delegate);
416         if (result != DistributedDB::DBStatus::OK) {
417             ZLOGE("CloseMetaKvStore return error status: %{public}d", static_cast<int>(result));
418         }
419     };
420     return NbDelegate(delegate, release);
421 }
422 
InitDBOption()423 DistributedDB::KvStoreNbDelegate::Option KvStoreMetaManager::InitDBOption()
424 {
425     DistributedDB::KvStoreNbDelegate::Option option;
426     option.createIfNecessary = true;
427     option.isMemoryDb = false;
428     option.createDirByStoreIdOnly = true;
429     option.isEncryptedDb = false;
430     option.isNeedIntegrityCheck = true;
431     option.isNeedRmCorruptedDb = false;
432     option.isNeedCompressOnSync = true;
433     option.compressionRate = COMPRESS_RATE;
434     option.secOption = { DistributedDB::S1, DistributedDB::ECE };
435     return option;
436 }
437 
SetCloudSyncer()438 void KvStoreMetaManager::SetCloudSyncer()
439 {
440     auto cloudSyncer = [this]() {
441         std::lock_guard<decltype(mutex_)> lock(mutex_);
442         if (delaySyncTaskId_ == Executor::INVALID_TASK_ID) {
443             delaySyncTaskId_ = executors_->Schedule(std::chrono::milliseconds(DELAY_SYNC), CloudSyncTask());
444         } else {
445             delaySyncTaskId_ = executors_->Reset(delaySyncTaskId_, std::chrono::milliseconds(DELAY_SYNC));
446         }
447     };
448     MetaDataManager::GetInstance().SetCloudSyncer(cloudSyncer);
449 }
450 
CloudSyncTask()451 std::function<void()> KvStoreMetaManager::CloudSyncTask()
452 {
453     return [this]() {
454         {
455             std::lock_guard<decltype(mutex_)> lock(mutex_);
456             delaySyncTaskId_ = ExecutorPool::INVALID_TASK_ID;
457         }
458         DeviceMatrix::GetInstance().OnChanged(DeviceMatrix::META_STORE_MASK);
459     };
460 }
461 
SubscribeMetaKvStore()462 void KvStoreMetaManager::SubscribeMetaKvStore()
463 {
464     auto metaDelegate = GetMetaKvStore();
465     if (metaDelegate == nullptr) {
466         ZLOGW("register meta observer failed.");
467         return;
468     }
469 
470     int mode = DistributedDB::OBSERVER_CHANGES_NATIVE | DistributedDB::OBSERVER_CHANGES_FOREIGN;
471     auto dbStatus = metaDelegate->RegisterObserver(DistributedDB::Key(), mode, &metaObserver_);
472     if (dbStatus != DistributedDB::DBStatus::OK) {
473         ZLOGW("register meta observer failed :%{public}d.", dbStatus);
474     }
475 }
476 
~KvStoreMetaObserver()477 KvStoreMetaManager::KvStoreMetaObserver::~KvStoreMetaObserver()
478 {
479     ZLOGW("meta observer destruct.");
480 }
481 
OnChange(const DistributedDB::KvStoreChangedData & data)482 void KvStoreMetaManager::KvStoreMetaObserver::OnChange(const DistributedDB::KvStoreChangedData &data)
483 {
484     ZLOGD("on data change.");
485     HandleChanges(CHANGE_FLAG::INSERT, data.GetEntriesInserted());
486     HandleChanges(CHANGE_FLAG::UPDATE, data.GetEntriesUpdated());
487     HandleChanges(CHANGE_FLAG::DELETE, data.GetEntriesDeleted());
488     KvStoreMetaManager::GetInstance().OnDataChange(CHANGE_FLAG::INSERT, data.GetEntriesInserted());
489     KvStoreMetaManager::GetInstance().OnDataChange(CHANGE_FLAG::UPDATE, data.GetEntriesUpdated());
490     KvStoreMetaManager::GetInstance().OnDataChange(CHANGE_FLAG::DELETE, data.GetEntriesDeleted());
491 }
492 
HandleChanges(CHANGE_FLAG flag,const std::list<DistributedDB::Entry> & entries)493 void KvStoreMetaManager::KvStoreMetaObserver::HandleChanges(CHANGE_FLAG flag,
494     const std::list<DistributedDB::Entry> &entries)
495 {
496     for (const auto &entry : entries) {
497         std::string key(entry.key.begin(), entry.key.end());
498         for (const auto &item : handlerMap_) {
499             ZLOGI("flag:%{public}d, key:%{public}s", flag, Anonymous::Change(key).c_str());
500             if (key.find(item.first) == 0) {
501                 item.second(entry.key, entry.value, flag);
502             }
503         }
504     }
505 }
506 
OnDeviceChanged(const AppDistributedKv::DeviceInfo & info,const AppDistributedKv::DeviceChangeType & type) const507 void KvStoreMetaManager::MetaDeviceChangeListenerImpl::OnDeviceChanged(const AppDistributedKv::DeviceInfo &info,
508     const AppDistributedKv::DeviceChangeType &type) const
509 {
510     if (info.uuid == DmAdapter::CLOUD_DEVICE_UUID) {
511         return;
512     }
513     switch (type) {
514         case AppDistributedKv::DeviceChangeType::DEVICE_OFFLINE:
515             DeviceMatrix::GetInstance().Offline(info.uuid);
516             break;
517         case AppDistributedKv::DeviceChangeType::DEVICE_ONLINE:
518             DeviceMatrix::GetInstance().Online(info.uuid, RefCount([deviceId = info.uuid]() {
519                 DmAdapter::GetInstance().NotifyReadyEvent(deviceId);
520             }));
521             break;
522         default:
523             ZLOGI("flag:%{public}d", type);
524             break;
525     }
526 }
527 
GetChangeLevelType() const528 AppDistributedKv::ChangeLevelType KvStoreMetaManager::MetaDeviceChangeListenerImpl::GetChangeLevelType() const
529 {
530     return AppDistributedKv::ChangeLevelType::LOW;
531 }
532 
GetBackupPath() const533 std::string KvStoreMetaManager::GetBackupPath() const
534 {
535     return (DirectoryManager::GetInstance().GetMetaBackupPath() + "/" +
536             Crypto::Sha256(label_ + "_" + Bootstrap::GetInstance().GetMetaDBName()));
537 }
538 
BindExecutor(std::shared_ptr<ExecutorPool> executors)539 void KvStoreMetaManager::BindExecutor(std::shared_ptr<ExecutorPool> executors)
540 {
541     executors_ = executors;
542 }
543 
OnDataChange(CHANGE_FLAG flag,const std::list<DistributedDB::Entry> & changedData)544 void KvStoreMetaManager::OnDataChange(CHANGE_FLAG flag, const std::list<DistributedDB::Entry>& changedData)
545 {
546     for (const auto& entry : changedData) {
547         std::string key(entry.key.begin(), entry.key.end());
548         if (key.find(StoreMetaData::GetKey({})) != 0) {
549             continue;
550         }
551         StoreMetaData metaData;
552         metaData.Unmarshall({ entry.value.begin(), entry.value.end() });
553         if (!metaData.isAutoSync) {
554             continue;
555         }
556         std::vector<DistributedDB::DBInfo> dbInfos;
557         AddDbInfo(metaData, dbInfos, flag == CHANGE_FLAG::DELETE);
558         DistributedDB::RuntimeConfig::NotifyDBInfos({ metaData.deviceId }, dbInfos);
559     }
560 }
561 
GetDbInfosByDeviceId(const std::string & deviceId,std::vector<DistributedDB::DBInfo> & dbInfos)562 void KvStoreMetaManager::GetDbInfosByDeviceId(const std::string& deviceId, std::vector<DistributedDB::DBInfo>& dbInfos)
563 {
564     std::vector<StoreMetaData> metaData;
565     if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ deviceId }), metaData)) {
566         ZLOGW("load meta failed, deviceId:%{public}s", Anonymous::Change(deviceId).c_str());
567         return;
568     }
569     for (auto const& data : metaData) {
570         if (data.isAutoSync) {
571             AddDbInfo(data, dbInfos);
572         }
573     }
574 }
575 
AddDbInfo(const StoreMetaData & metaData,std::vector<DistributedDB::DBInfo> & dbInfos,bool isDeleted)576 void KvStoreMetaManager::AddDbInfo(const StoreMetaData& metaData, std::vector<DistributedDB::DBInfo>& dbInfos,
577     bool isDeleted)
578 {
579     DistributedDB::DBInfo dbInfo;
580     dbInfo.appId = metaData.deviceId;
581     dbInfo.userId = metaData.user;
582     dbInfo.storeId = metaData.storeId;
583     dbInfo.isNeedSync = !isDeleted;
584     dbInfo.syncDualTupleMode = true;
585     dbInfos.push_back(dbInfo);
586 }
587 
OnDeviceChange(const std::string & deviceId)588 void KvStoreMetaManager::OnDeviceChange(const std::string& deviceId)
589 {
590     std::vector<DistributedDB::DBInfo> dbInfos;
591     GetDbInfosByDeviceId(deviceId, dbInfos);
592     DistributedDB::RuntimeConfig::NotifyDBInfos({ deviceId }, dbInfos);
593 }
594 
NotifyAllAutoSyncDBInfo()595 void KvStoreMetaManager::NotifyAllAutoSyncDBInfo()
596 {
597     auto deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
598     if (deviceId.empty()) {
599         ZLOGE("local deviceId empty");
600         return;
601     }
602     std::vector<StoreMetaData> metaData;
603     if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ deviceId }), metaData)) {
604         ZLOGE("load meta failed, deviceId:%{public}s", Anonymous::Change(deviceId).c_str());
605         return;
606     }
607     std::vector<DistributedDB::DBInfo> dbInfos;
608     for (auto const& data : metaData) {
609         if (!data.isAutoSync) {
610             continue;
611         }
612         AddDbInfo(data, dbInfos);
613     }
614     if (!dbInfos.empty()) {
615         DistributedDB::RuntimeConfig::NotifyDBInfos({ deviceId }, dbInfos);
616     }
617 }
618 
OnDeviceChanged(const AppDistributedKv::DeviceInfo & info,const DeviceChangeType & type) const619 void KvStoreMetaManager::DBInfoDeviceChangeListenerImpl::OnDeviceChanged(const AppDistributedKv::DeviceInfo& info,
620     const DeviceChangeType& type) const
621 {
622     if (type != DeviceChangeType::DEVICE_ONLINE) {
623         ZLOGD("offline or onReady ignore, type:%{public}d, deviceId:%{public}s", type,
624             Anonymous::Change(info.uuid).c_str());
625         return;
626     }
627     if (info.uuid == DistributedData::DeviceManagerAdapter::CLOUD_DEVICE_UUID) {
628         ZLOGD("Network change, ignore");
629         return;
630     }
631     KvStoreMetaManager::GetInstance().OnDeviceChange(info.uuid);
632 }
633 
GetChangeLevelType() const634 AppDistributedKv::ChangeLevelType KvStoreMetaManager::DBInfoDeviceChangeListenerImpl::GetChangeLevelType() const
635 {
636     return AppDistributedKv::ChangeLevelType::MIN;
637 }
638 
CheckMetaDeviceId()639 void KvStoreMetaManager::CheckMetaDeviceId()
640 {
641     DeviceMetaData deviceMeta;
642     auto localUuid = DmAdapter::GetInstance().GetLocalDevice().uuid;
643     if (localUuid.empty()) {
644         ZLOGW("get uuid failed");
645         return;
646     }
647     if (!MetaDataManager::GetInstance().LoadMeta(deviceMeta.GetKey(), deviceMeta, true)) {
648         deviceMeta.newUuid = localUuid;
649         MetaDataManager::GetInstance().SaveMeta(deviceMeta.GetKey(), deviceMeta, true);
650         return;
651     }
652     if (deviceMeta.newUuid != localUuid) {
653         UpdateStoreMetaData(localUuid, deviceMeta.newUuid);
654         UpdateMetaDatas(localUuid, deviceMeta.newUuid);
655         ZLOGI("meta changed! cur uuid:%{public}s, old uuid:%{public}s", Anonymous::Change(localUuid).c_str(),
656             Anonymous::Change(deviceMeta.newUuid).c_str());
657         deviceMeta.newUuid = localUuid;
658         MetaDataManager::GetInstance().SaveMeta(deviceMeta.GetKey(), deviceMeta, true);
659     }
660 }
661 
UpdateStoreMetaData(const std::string & newUuid,const std::string & oldUuid)662 void KvStoreMetaManager::UpdateStoreMetaData(const std::string &newUuid, const std::string &oldUuid)
663 {
664     std::vector<StoreMetaData> storeMetas;
665     MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ oldUuid }), storeMetas, true);
666     for (auto &storeMeta : storeMetas) {
667         auto oldMeta = storeMeta;
668         storeMeta.isNeedUpdateDeviceId = true;
669         storeMeta.deviceId = newUuid;
670         MetaDataManager::GetInstance().SaveMeta(storeMeta.GetKey(), storeMeta, true);
671         MetaDataManager::GetInstance().DelMeta(oldMeta.GetKey(), true);
672 
673         StoreMetaData syncStoreMeta;
674         if (MetaDataManager::GetInstance().LoadMeta(oldMeta.GetKeyWithoutPath(), syncStoreMeta)) {
675             syncStoreMeta.deviceId = newUuid;
676             MetaDataManager::GetInstance().SaveMeta(storeMeta.GetKeyWithoutPath(), syncStoreMeta);
677             MetaDataManager::GetInstance().DelMeta(oldMeta.GetKeyWithoutPath());
678         }
679 
680         StrategyMeta strategyMeta;
681         if (MetaDataManager::GetInstance().LoadMeta(oldMeta.GetStrategyKey(), strategyMeta)) {
682             strategyMeta.devId = newUuid;
683             MetaDataManager::GetInstance().SaveMeta(storeMeta.GetStrategyKey(), strategyMeta);
684             MetaDataManager::GetInstance().DelMeta(oldMeta.GetStrategyKey());
685         }
686 
687         StoreMetaDataLocal metaDataLocal;
688         if (MetaDataManager::GetInstance().LoadMeta(oldMeta.GetKeyLocal(), metaDataLocal, true)) {
689             MetaDataManager::GetInstance().SaveMeta(storeMeta.GetKeyLocal(), metaDataLocal, true);
690             MetaDataManager::GetInstance().DelMeta(oldMeta.GetKeyLocal(), true);
691         }
692 
693         AutoLaunchMetaData autoLaunchMetaData;
694         bool isExist = MetaDataManager::GetInstance().LoadMeta(oldMeta.GetAutoLaunchKey(), autoLaunchMetaData, true);
695         if (!isExist) {
696             oldMeta.storeId = "";
697             isExist = MetaDataManager::GetInstance().LoadMeta(oldMeta.GetAutoLaunchKey(), autoLaunchMetaData, true);
698         }
699         if (isExist) {
700             MetaDataManager::GetInstance().DelMeta(oldMeta.GetAutoLaunchKey(), true);
701             oldMeta.deviceId = newUuid;
702             MetaDataManager::GetInstance().SaveMeta(oldMeta.GetAutoLaunchKey(), autoLaunchMetaData, true);
703         }
704         if (storeMeta.isEncrypt) {
705             MetaDataManager::GetInstance().DelMeta(storeMeta.GetSecretKey(), true);
706             MetaDataManager::GetInstance().DelMeta(storeMeta.GetCloneSecretKey(), true);
707         }
708         MetaDataManager::GetInstance().DelMeta(oldMeta.GetDebugInfoKey(), true);
709         MetaDataManager::GetInstance().DelMeta(oldMeta.GetDfxInfoKey(), true);
710     }
711     UpdateStoreMetaMapping(newUuid, oldUuid);
712 }
713 
UpdateStoreMetaMapping(const std::string & newUuid,const std::string & oldUuid)714 void KvStoreMetaManager::UpdateStoreMetaMapping(const std::string &newUuid, const std::string &oldUuid)
715 {
716     std::vector<StoreMetaMapping> storeMetaMappings;
717     MetaDataManager::GetInstance().LoadMeta(StoreMetaMapping::GetPrefix({ oldUuid }), storeMetaMappings, true);
718     for (auto &meta : storeMetaMappings) {
719         auto oldKey = meta.GetKey();
720         meta.deviceId = newUuid;
721         MetaDataManager::GetInstance().SaveMeta(meta.GetKey(), meta, true);
722         MetaDataManager::GetInstance().DelMeta(oldKey, true);
723     }
724 }
725 
UpdateMetaDatas(const std::string & newUuid,const std::string & oldUuid)726 void KvStoreMetaManager::UpdateMetaDatas(const std::string &newUuid, const std::string &oldUuid)
727 {
728     MatrixMetaData matrixMeta;
729     if (MetaDataManager::GetInstance().LoadMeta(MatrixMetaData::GetPrefix({ oldUuid }), matrixMeta, true)) {
730         MetaDataManager::GetInstance().DelMeta(MatrixMetaData::GetPrefix({ oldUuid }), true);
731         matrixMeta.deviceId = newUuid;
732         MetaDataManager::GetInstance().SaveMeta(MatrixMetaData::GetPrefix({ newUuid }), matrixMeta, true);
733     }
734 
735     if (MetaDataManager::GetInstance().LoadMeta(MatrixMetaData::GetPrefix({ oldUuid }), matrixMeta)) {
736         MetaDataManager::GetInstance().DelMeta(MatrixMetaData::GetPrefix({ oldUuid }));
737         matrixMeta.deviceId = newUuid;
738         MetaDataManager::GetInstance().SaveMeta(MatrixMetaData::GetPrefix({ newUuid }), matrixMeta);
739     }
740 
741     SwitchesMetaData switchesMetaData;
742     if (MetaDataManager::GetInstance().LoadMeta(SwitchesMetaData::GetPrefix({ oldUuid }),
743         switchesMetaData, true)) {
744         MetaDataManager::GetInstance().DelMeta(SwitchesMetaData::GetPrefix({ oldUuid }), true);
745         switchesMetaData.deviceId = newUuid;
746         MetaDataManager::GetInstance().SaveMeta(SwitchesMetaData::GetPrefix({ newUuid }),
747             switchesMetaData, true);
748     }
749 
750     UserMetaData userMeta;
751     if (MetaDataManager::GetInstance().LoadMeta(UserMetaRow::GetKeyFor(oldUuid), userMeta)) {
752         MetaDataManager::GetInstance().DelMeta(UserMetaRow::GetKeyFor(oldUuid));
753         userMeta.deviceId = newUuid;
754         MetaDataManager::GetInstance().SaveMeta(UserMetaRow::GetKeyFor(newUuid), userMeta);
755     }
756 
757     CapMetaData capMetaData;
758     auto capKey = CapMetaRow::GetKeyFor(oldUuid);
759     if (MetaDataManager::GetInstance().LoadMeta(std::string(capKey.begin(), capKey.end()), capMetaData)) {
760         auto newCapKey = CapMetaRow::GetKeyFor(newUuid);
761         MetaDataManager::GetInstance().DelMeta(std::string(capKey.begin(), capKey.end()));
762         MetaDataManager::GetInstance().SaveMeta(std::string(newCapKey.begin(), newCapKey.end()), capMetaData);
763     }
764 }
765 } // namespace DistributedKv
766 } // namespace OHOS