• 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 "KvStoreDataService"
16 #include "kvstore_data_service.h"
17 
18 #include <chrono>
19 #include <ipc_skeleton.h>
20 #include <thread>
21 
22 #include "accesstoken_kit.h"
23 #include "auth_delegate.h"
24 #include "auto_launch_export.h"
25 #include "bootstrap.h"
26 #include "checker/checker_manager.h"
27 #include "communication_provider.h"
28 #include "communicator_context.h"
29 #include "config_factory.h"
30 #include "crypto_manager.h"
31 #include "db_info_handle_impl.h"
32 #include "device_manager_adapter.h"
33 #include "device_matrix.h"
34 #include "dump/dump_manager.h"
35 #include "dump_helper.h"
36 #include "eventcenter/event_center.h"
37 #include "if_system_ability_manager.h"
38 #include "iservice_registry.h"
39 #include "kvstore_account_observer.h"
40 #include "log_print.h"
41 #include "metadata/appid_meta_data.h"
42 #include "metadata/meta_data_manager.h"
43 #include "metadata/secret_key_meta_data.h"
44 #include "permission_validator.h"
45 #include "permit_delegate.h"
46 #include "process_communicator_impl.h"
47 #include "reporter.h"
48 #include "route_head_handler_impl.h"
49 #include "runtime_config.h"
50 #include "store/auto_cache.h"
51 #include "string_ex.h"
52 #include "system_ability_definition.h"
53 #include "task_manager.h"
54 #include "installer/installer.h"
55 #include "upgrade.h"
56 #include "upgrade_manager.h"
57 #include "user_delegate.h"
58 #include "utils/anonymous.h"
59 #include "utils/block_integer.h"
60 #include "utils/crypto.h"
61 
62 namespace OHOS::DistributedKv {
63 using namespace std::chrono;
64 using namespace OHOS::DistributedData;
65 using namespace OHOS::DistributedDataDfx;
66 using namespace OHOS::Security::AccessToken;
67 using KvStoreDelegateManager = DistributedDB::KvStoreDelegateManager;
68 using SecretKeyMeta = DistributedData::SecretKeyMetaData;
69 using DmAdapter = DistributedData::DeviceManagerAdapter;
70 using DBConfig = DistributedDB::RuntimeConfig;
71 
72 REGISTER_SYSTEM_ABILITY_BY_ID(KvStoreDataService, DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID, true);
73 
KvStoreDataService(bool runOnCreate)74 KvStoreDataService::KvStoreDataService(bool runOnCreate)
75     : SystemAbility(runOnCreate), mutex_(), clients_()
76 {
77     ZLOGI("begin.");
78     if (executors_ == nullptr) {
79         constexpr size_t MAX = 12;
80         constexpr size_t MIN = 5;
81         executors_ = std::make_shared<ExecutorPool>(MAX, MIN);
82         DistributedDB::RuntimeConfig::SetThreadPool(std::make_shared<TaskManager>(executors_));
83     }
84 }
85 
KvStoreDataService(int32_t systemAbilityId,bool runOnCreate)86 KvStoreDataService::KvStoreDataService(int32_t systemAbilityId, bool runOnCreate)
87     : SystemAbility(systemAbilityId, runOnCreate), mutex_(), clients_()
88 {
89     ZLOGI("begin");
90     if (executors_ == nullptr) {
91         constexpr size_t MAX = 12;
92         constexpr size_t MIN = 5;
93         executors_ = std::make_shared<ExecutorPool>(MAX, MIN);
94         DistributedDB::RuntimeConfig::SetThreadPool(std::make_shared<TaskManager>(executors_));
95     }
96 }
97 
~KvStoreDataService()98 KvStoreDataService::~KvStoreDataService()
99 {
100     ZLOGI("begin.");
101     clients_.clear();
102     features_.Clear();
103 }
104 
Initialize()105 void KvStoreDataService::Initialize()
106 {
107     ZLOGI("begin.");
108 #ifndef UT_TEST
109     KvStoreDelegateManager::SetProcessLabel(Bootstrap::GetInstance().GetProcessLabel(), "default");
110 #endif
111     CommunicatorContext::GetInstance().SetThreadPool(executors_);
112     auto communicator = std::make_shared<AppDistributedKv::ProcessCommunicatorImpl>(RouteHeadHandlerImpl::Create);
113     auto ret = KvStoreDelegateManager::SetProcessCommunicator(communicator);
114     ZLOGI("set communicator ret:%{public}d.", static_cast<int>(ret));
115 
116     AppDistributedKv::CommunicationProvider::GetInstance();
117     PermitDelegate::GetInstance().Init();
118     InitSecurityAdapter(executors_);
119     KvStoreMetaManager::GetInstance().BindExecutor(executors_);
120     KvStoreMetaManager::GetInstance().InitMetaParameter();
121     accountEventObserver_ = std::make_shared<KvStoreAccountObserver>(*this, executors_);
122     AccountDelegate::GetInstance()->Subscribe(accountEventObserver_);
123     deviceInnerListener_ = std::make_unique<KvStoreDeviceListener>(*this);
124     DmAdapter::GetInstance().StartWatchDeviceChange(deviceInnerListener_.get(), { "innerListener" });
125     auto translateCall = [](const std::string &oriDevId, const DistributedDB::StoreInfo &info) {
126         StoreMetaData meta;
127         AppIDMetaData appIdMeta;
128         MetaDataManager::GetInstance().LoadMeta(info.appId, appIdMeta, true);
129         meta.bundleName = appIdMeta.bundleName;
130         meta.storeId = info.storeId;
131         meta.user = info.userId;
132         meta.deviceId = oriDevId;
133         MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta);
134         return Upgrade::GetInstance().GetEncryptedUuidByMeta(meta);
135     };
136     DBConfig::SetTranslateToDeviceIdCallback(translateCall);
137     DistributedDB::RuntimeConfig::SetDBInfoHandle(std::make_shared<DBInfoHandleImpl>());
138 }
139 
GetFeatureInterface(const std::string & name)140 sptr<IRemoteObject> KvStoreDataService::GetFeatureInterface(const std::string &name)
141 {
142     sptr<FeatureStubImpl> feature;
143     bool isFirstCreate = false;
144     features_.Compute(name, [&feature, &isFirstCreate](const auto &key, auto &value) ->bool {
145         if (value != nullptr) {
146             feature = value;
147             return true;
148         }
149         auto creator = FeatureSystem::GetInstance().GetCreator(key);
150         if (!creator) {
151             return false;
152         }
153         auto impl = creator();
154         if (impl == nullptr) {
155             return false;
156         }
157 
158         value = new FeatureStubImpl(impl);
159         feature = value;
160         isFirstCreate = true;
161         return true;
162     });
163     if (isFirstCreate) {
164         feature->OnInitialize(executors_);
165     }
166     return feature != nullptr ? feature->AsObject() : nullptr;
167 }
168 
LoadFeatures()169 void KvStoreDataService::LoadFeatures()
170 {
171     ZLOGI("begin.");
172     auto features = FeatureSystem::GetInstance().GetFeatureName(FeatureSystem::BIND_NOW);
173     for (auto const &feature : features) {
174         GetFeatureInterface(feature);
175     }
176 }
177 
178 /* RegisterClientDeathObserver */
RegisterClientDeathObserver(const AppId & appId,sptr<IRemoteObject> observer)179 Status KvStoreDataService::RegisterClientDeathObserver(const AppId &appId, sptr<IRemoteObject> observer)
180 {
181     ZLOGD("begin.");
182     KVSTORE_ACCOUNT_EVENT_PROCESSING_CHECKER(Status::SYSTEM_ACCOUNT_EVENT_PROCESSING);
183     if (!appId.IsValid()) {
184         ZLOGE("invalid bundleName, name:%{public}s", appId.appId.c_str());
185         return Status::INVALID_ARGUMENT;
186     }
187 
188     CheckerManager::StoreInfo info;
189     info.uid = IPCSkeleton::GetCallingUid();
190     info.tokenId = IPCSkeleton::GetCallingTokenID();
191     info.bundleName = appId.appId;
192     info.storeId = "";
193     if (!CheckerManager::GetInstance().IsValid(info)) {
194         ZLOGW("check bundleName:%{public}s uid:%{public}d failed.", appId.appId.c_str(), info.uid);
195         return Status::PERMISSION_DENIED;
196     }
197 
198     std::lock_guard<decltype(mutex_)> lg(mutex_);
199     auto iter = clients_.find(info.tokenId);
200     // Ignore register with same tokenId and pid
201     if (iter != clients_.end() && IPCSkeleton::GetCallingPid() == iter->second.GetPid()) {
202         ZLOGW("bundleName:%{public}s, uid:%{public}d, pid:%{public}d has already registered.",
203             appId.appId.c_str(), info.uid, IPCSkeleton::GetCallingPid());
204         return Status::SUCCESS;
205     }
206 
207     clients_.erase(info.tokenId);
208     auto it = clients_.emplace(std::piecewise_construct, std::forward_as_tuple(info.tokenId),
209         std::forward_as_tuple(appId, *this, std::move(observer)));
210     ZLOGI("bundleName:%{public}s, uid:%{public}d, pid:%{public}d inserted:%{public}s.",
211         appId.appId.c_str(), info.uid, IPCSkeleton::GetCallingPid(), it.second ? "success" : "failed");
212     return it.second ? Status::SUCCESS : Status::ERROR;
213 }
214 
AppExit(pid_t uid,pid_t pid,uint32_t token,const AppId & appId)215 Status KvStoreDataService::AppExit(pid_t uid, pid_t pid, uint32_t token, const AppId &appId)
216 {
217     ZLOGI("AppExit");
218     // memory of parameter appId locates in a member of clientDeathObserverMap_ and will be freed after
219     // clientDeathObserverMap_ erase, so we have to take a copy if we want to use this parameter after erase operation.
220     AppId appIdTmp = appId;
221     std::lock_guard<decltype(mutex_)> lg(mutex_);
222     clients_.erase(token);
223     return Status::SUCCESS;
224 }
225 
OnDump()226 void KvStoreDataService::OnDump()
227 {
228     ZLOGD("begin.");
229 }
230 
Dump(int fd,const std::vector<std::u16string> & args)231 int KvStoreDataService::Dump(int fd, const std::vector<std::u16string> &args)
232 {
233     int uid = static_cast<int>(IPCSkeleton::GetCallingUid());
234     const int maxUid = 10000;
235     if (uid > maxUid) {
236         return 0;
237     }
238 
239     std::vector<std::string> argsStr;
240     for (auto item : args) {
241         argsStr.emplace_back(Str16ToStr8(item));
242     }
243 
244     if (DumpHelper::GetInstance().Dump(fd, argsStr)) {
245         return 0;
246     }
247 
248     ZLOGE("DumpHelper failed");
249     return ERROR;
250 }
251 
OnStart()252 void KvStoreDataService::OnStart()
253 {
254     ZLOGI("distributeddata service onStart");
255     EventCenter::Defer defer;
256     Reporter::GetInstance()->SetThreadPool(executors_);
257     AccountDelegate::GetInstance()->BindExecutor(executors_);
258     AccountDelegate::GetInstance()->RegisterHashFunc(Crypto::Sha256);
259     DmAdapter::GetInstance().Init(executors_);
260     AutoCache::GetInstance().Bind(executors_);
261     static constexpr int32_t RETRY_TIMES = 50;
262     static constexpr int32_t RETRY_INTERVAL = 500 * 1000; // unit is ms
263     for (BlockInteger retry(RETRY_INTERVAL); retry < RETRY_TIMES; ++retry) {
264         if (!DmAdapter::GetInstance().GetLocalDevice().uuid.empty()) {
265             break;
266         }
267         ZLOGW("GetLocalDeviceId failed, retry count:%{public}d", static_cast<int>(retry));
268     }
269     ZLOGI("Bootstrap configs and plugins.");
270     Bootstrap::GetInstance().LoadComponents();
271     Bootstrap::GetInstance().LoadDirectory();
272     Bootstrap::GetInstance().LoadCheckers();
273     Bootstrap::GetInstance().LoadNetworks();
274     Bootstrap::GetInstance().LoadBackup(executors_);
275     Initialize();
276     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
277     if (samgr != nullptr) {
278         ZLOGI("samgr exist.");
279         auto remote = samgr->CheckSystemAbility(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID);
280         auto kvDataServiceProxy = iface_cast<IKvStoreDataService>(remote);
281         if (kvDataServiceProxy != nullptr) {
282             ZLOGI("service has been registered.");
283             return;
284         }
285     }
286     AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
287     RegisterStoreInfo();
288     Handler handlerStoreInfo = std::bind(&KvStoreDataService::DumpStoreInfo, this, std::placeholders::_1,
289         std::placeholders::_2);
290     DumpManager::GetInstance().AddHandler("STORE_INFO", uintptr_t(this), handlerStoreInfo);
291     RegisterUserInfo();
292     Handler handlerUserInfo = std::bind(&KvStoreDataService::DumpUserInfo, this, std::placeholders::_1,
293         std::placeholders::_2);
294     DumpManager::GetInstance().AddHandler("USER_INFO", uintptr_t(this), handlerUserInfo);
295     RegisterBundleInfo();
296     Handler handlerBundleInfo = std::bind(&KvStoreDataService::DumpBundleInfo, this, std::placeholders::_1,
297         std::placeholders::_2);
298     DumpManager::GetInstance().AddHandler("BUNDLE_INFO", uintptr_t(this), handlerBundleInfo);
299     StartService();
300 }
301 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)302 void KvStoreDataService::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
303 {
304     ZLOGI("add system abilityid:%{public}d", systemAbilityId);
305     (void)deviceId;
306     if (systemAbilityId != COMMON_EVENT_SERVICE_ID) {
307         return;
308     }
309     AccountDelegate::GetInstance()->SubscribeAccountEvent();
310     Installer::GetInstance().Init(this, executors_);
311 }
312 
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)313 void KvStoreDataService::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
314 {
315     ZLOGI("remove system abilityid:%{public}d", systemAbilityId);
316     (void)deviceId;
317     if (systemAbilityId != COMMON_EVENT_SERVICE_ID) {
318         return;
319     }
320     AccountDelegate::GetInstance()->UnsubscribeAccountEvent();
321     Installer::GetInstance().UnsubscribeEvent();
322 }
323 
StartService()324 void KvStoreDataService::StartService()
325 {
326     // register this to ServiceManager.
327     ZLOGI("begin.");
328     KvStoreMetaManager::GetInstance().InitMetaListener();
329     DeviceMatrix::GetInstance().Initialize(IPCSkeleton::GetCallingTokenID(), Bootstrap::GetInstance().GetMetaDBName());
330     LoadFeatures();
331     bool ret = SystemAbility::Publish(this);
332     if (!ret) {
333         DumpHelper::GetInstance().AddErrorInfo(SERVER_UNAVAILABLE, "StartService: Service publish failed.");
334     }
335     // Initialize meta db delegate manager.
336     KvStoreMetaManager::GetInstance().SubscribeMeta(StoreMetaData::GetKey({}),
337         [this](const std::vector<uint8_t> &key, const std::vector<uint8_t> &value, CHANGE_FLAG flag) {
338             OnStoreMetaChanged(key, value, flag);
339         });
340     UpgradeManager::GetInstance().Init(executors_);
341     UserDelegate::GetInstance().Init(executors_);
342 
343     // subscribe account event listener to EventNotificationMgr
344     auto autoLaunch = [this](const std::string &identifier, DistributedDB::AutoLaunchParam &param) -> bool {
345         auto status = ResolveAutoLaunchParamByIdentifier(identifier, param);
346         features_.ForEachCopies([&identifier, &param](const auto &, sptr<DistributedData::FeatureStubImpl> &value) {
347             value->ResolveAutoLaunch(identifier, param);
348             return false;
349         });
350         return status;
351     };
352     KvStoreDelegateManager::SetAutoLaunchRequestCallback(autoLaunch);
353     ZLOGI("Publish ret: %{public}d", static_cast<int>(ret));
354 }
355 
OnStoreMetaChanged(const std::vector<uint8_t> & key,const std::vector<uint8_t> & value,CHANGE_FLAG flag)356 void KvStoreDataService::OnStoreMetaChanged(
357     const std::vector<uint8_t> &key, const std::vector<uint8_t> &value, CHANGE_FLAG flag)
358 {
359     if (flag != CHANGE_FLAG::UPDATE) {
360         return;
361     }
362     StoreMetaData metaData;
363     metaData.Unmarshall({ value.begin(), value.end() });
364     ZLOGD("meta data info appType:%{public}s, storeId:%{public}s isDirty:%{public}d", metaData.appType.c_str(),
365         Anonymous::Change(metaData.storeId).c_str(), metaData.isDirty);
366     auto deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
367     if (metaData.deviceId != deviceId || metaData.deviceId.empty()) {
368         ZLOGD("ignore other device change or invalid meta device");
369         return;
370     }
371     static constexpr const char *HARMONY_APP = "harmony";
372     if (!metaData.isDirty || metaData.appType != HARMONY_APP) {
373         return;
374     }
375     ZLOGI("dirty kv store. storeId:%{public}s", Anonymous::Change(metaData.storeId).c_str());
376 }
377 
ResolveAutoLaunchParamByIdentifier(const std::string & identifier,DistributedDB::AutoLaunchParam & param)378 bool KvStoreDataService::ResolveAutoLaunchParamByIdentifier(
379     const std::string &identifier, DistributedDB::AutoLaunchParam &param)
380 {
381     ZLOGI("start");
382     std::vector<StoreMetaData> entries;
383     std::string localDeviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
384     if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ localDeviceId }), entries)) {
385         ZLOGE("get full meta failed");
386         return false;
387     }
388 
389     for (const auto &storeMeta : entries) {
390         if ((!param.userId.empty() && (param.userId != storeMeta.user)) || (localDeviceId != storeMeta.deviceId) ||
391             ((StoreMetaData::STORE_RELATIONAL_BEGIN <= storeMeta.storeType) &&
392              (StoreMetaData::STORE_RELATIONAL_END >= storeMeta.storeType))) {
393             // judge local userid and local meta
394             continue;
395         }
396         const std::string &itemTripleIdentifier =
397             DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(storeMeta.user, storeMeta.appId,
398                 storeMeta.storeId, false);
399         const std::string &itemDualIdentifier =
400             DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier("", storeMeta.appId, storeMeta.storeId, true);
401         if (identifier == itemTripleIdentifier && storeMeta.bundleName != Bootstrap::GetInstance().GetProcessLabel()) {
402             // old triple tuple identifier, should SetEqualIdentifier
403             ResolveAutoLaunchCompatible(storeMeta, identifier);
404         }
405         if (identifier == itemDualIdentifier || identifier == itemTripleIdentifier) {
406             ZLOGI("identifier  find");
407             DistributedDB::AutoLaunchOption option;
408             option.createIfNecessary = false;
409             option.isEncryptedDb = storeMeta.isEncrypt;
410 
411             SecretKeyMeta secretKey;
412             if (storeMeta.isEncrypt && MetaDataManager::GetInstance().LoadMeta(storeMeta.GetSecretKey(), secretKey)) {
413                 std::vector<uint8_t> decryptKey;
414                 CryptoManager::GetInstance().Decrypt(secretKey.sKey, decryptKey);
415                 option.passwd.SetValue(decryptKey.data(), decryptKey.size());
416                 std::fill(decryptKey.begin(), decryptKey.end(), 0);
417             }
418 
419             if (storeMeta.bundleName == Bootstrap::GetInstance().GetProcessLabel()) {
420                 param.userId = storeMeta.user;
421             }
422             option.schema = storeMeta.schema;
423             option.createDirByStoreIdOnly = true;
424             option.dataDir = storeMeta.dataDir;
425             option.secOption = ConvertSecurity(storeMeta.securityLevel);
426             option.isAutoSync = storeMeta.isAutoSync;
427             option.syncDualTupleMode = true; // dual tuple flag
428             param.appId = storeMeta.appId;
429             param.storeId = storeMeta.storeId;
430             param.option = option;
431             return true;
432         }
433     }
434     ZLOGI("not find identifier");
435     return false;
436 }
437 
ConvertSecurity(int securityLevel)438 DistributedDB::SecurityOption KvStoreDataService::ConvertSecurity(int securityLevel)
439 {
440     if (securityLevel < SecurityLevel::NO_LABEL || securityLevel > SecurityLevel::S4) {
441         return {DistributedDB::NOT_SET, DistributedDB::ECE};
442     }
443     switch (securityLevel) {
444         case SecurityLevel::S3:
445             return {DistributedDB::S3, DistributedDB::SECE};
446         case SecurityLevel::S4:
447             return {DistributedDB::S4, DistributedDB::ECE};
448         default:
449             return {securityLevel, DistributedDB::ECE};
450     }
451 }
452 
ResolveAutoLaunchCompatible(const StoreMetaData & storeMeta,const std::string & identifier)453 void KvStoreDataService::ResolveAutoLaunchCompatible(const StoreMetaData &storeMeta, const std::string &identifier)
454 {
455     ZLOGI("AutoLaunch:peer device is old tuple, begin to open store");
456     if (storeMeta.storeType > KvStoreType::SINGLE_VERSION || storeMeta.version > STORE_VERSION) {
457         ZLOGW("no longer support multi or higher version store type");
458         return;
459     }
460 
461     // open store and SetEqualIdentifier, then close store after 60s
462     DistributedDB::KvStoreDelegateManager delegateManager(storeMeta.appId, storeMeta.user);
463     delegateManager.SetKvStoreConfig({ storeMeta.dataDir });
464     Options options = {
465         .createIfMissing = false,
466         .encrypt = storeMeta.isEncrypt,
467         .autoSync = storeMeta.isAutoSync,
468         .securityLevel = storeMeta.securityLevel,
469         .kvStoreType = static_cast<KvStoreType>(storeMeta.storeType),
470     };
471     DistributedDB::KvStoreNbDelegate::Option dbOptions;
472     SecretKeyMeta secretKey;
473     if (storeMeta.isEncrypt && MetaDataManager::GetInstance().LoadMeta(storeMeta.GetSecretKey(), secretKey)) {
474         std::vector<uint8_t> decryptKey;
475         CryptoManager::GetInstance().Decrypt(secretKey.sKey, decryptKey);
476         std::fill(secretKey.sKey.begin(), secretKey.sKey.end(), 0);
477         secretKey.sKey = std::move(decryptKey);
478         std::fill(decryptKey.begin(), decryptKey.end(), 0);
479     }
480     InitNbDbOption(options, secretKey.sKey, dbOptions);
481     DistributedDB::KvStoreNbDelegate *store = nullptr;
482     delegateManager.GetKvStore(storeMeta.storeId, dbOptions,
483         [&store, &storeMeta](int status, DistributedDB::KvStoreNbDelegate *delegate) {
484             ZLOGI("temporary open db for equal identifier, ret:%{public}d", status);
485             if (delegate != nullptr) {
486                 KvStoreTuple tuple = { storeMeta.user, storeMeta.appId, storeMeta.storeId };
487                 UpgradeManager::SetCompatibleIdentifyByType(delegate, tuple, IDENTICAL_ACCOUNT_GROUP);
488                 UpgradeManager::SetCompatibleIdentifyByType(delegate, tuple, PEER_TO_PEER_GROUP);
489                 store = delegate;
490             }
491         });
492     ExecutorPool::Task delayTask([store]() {
493         ZLOGI("AutoLaunch:close store after 60s while autolaunch finishied");
494         DistributedDB::KvStoreDelegateManager delegateManager("", "");
495         delegateManager.CloseKvStore(store);
496     });
497     constexpr int CLOSE_STORE_DELAY_TIME = 60; // unit: seconds
498     executors_->Schedule(std::chrono::seconds(CLOSE_STORE_DELAY_TIME), std::move(delayTask));
499 }
500 
InitNbDbOption(const Options & options,const std::vector<uint8_t> & cipherKey,DistributedDB::KvStoreNbDelegate::Option & dbOption)501 Status KvStoreDataService::InitNbDbOption(const Options &options, const std::vector<uint8_t> &cipherKey,
502     DistributedDB::KvStoreNbDelegate::Option &dbOption)
503 {
504     DistributedDB::CipherPassword password;
505     auto status = password.SetValue(cipherKey.data(), cipherKey.size());
506     if (status != DistributedDB::CipherPassword::ErrorCode::OK) {
507         ZLOGE("Failed to set the passwd.");
508         return Status::DB_ERROR;
509     }
510 
511     dbOption.syncDualTupleMode = true; // tuple of (appid+storeid)
512     dbOption.createIfNecessary = options.createIfMissing;
513     dbOption.isMemoryDb = (!options.persistent);
514     dbOption.isEncryptedDb = options.encrypt;
515     if (options.encrypt) {
516         dbOption.cipher = DistributedDB::CipherType::AES_256_GCM;
517         dbOption.passwd = password;
518     }
519 
520     if (options.kvStoreType == KvStoreType::SINGLE_VERSION) {
521         dbOption.conflictResolvePolicy = DistributedDB::LAST_WIN;
522     } else if (options.kvStoreType == KvStoreType::DEVICE_COLLABORATION) {
523         dbOption.conflictResolvePolicy = DistributedDB::DEVICE_COLLABORATION;
524     } else {
525         ZLOGE("kvStoreType is invalid");
526         return Status::INVALID_ARGUMENT;
527     }
528 
529     dbOption.schema = options.schema;
530     dbOption.createDirByStoreIdOnly = true;
531     dbOption.secOption = ConvertSecurity(options.securityLevel);
532     return Status::SUCCESS;
533 }
534 
OnStop()535 void KvStoreDataService::OnStop()
536 {
537     ZLOGI("begin.");
538 }
539 
KvStoreClientDeathObserverImpl(const AppId & appId,KvStoreDataService & service,sptr<IRemoteObject> observer)540 KvStoreDataService::KvStoreClientDeathObserverImpl::KvStoreClientDeathObserverImpl(
541     const AppId &appId, KvStoreDataService &service, sptr<IRemoteObject> observer)
542     : appId_(appId), dataService_(service), observerProxy_(std::move(observer)),
543       deathRecipient_(new KvStoreDeathRecipient(*this))
544 {
545     ZLOGD("KvStoreClientDeathObserverImpl");
546     uid_ = IPCSkeleton::GetCallingUid();
547     pid_ = IPCSkeleton::GetCallingPid();
548     token_ = IPCSkeleton::GetCallingTokenID();
549     if (observerProxy_ != nullptr) {
550         ZLOGI("add death recipient");
551         observerProxy_->AddDeathRecipient(deathRecipient_);
552     } else {
553         ZLOGW("observerProxy_ is nullptr");
554     }
555 }
556 
~KvStoreClientDeathObserverImpl()557 KvStoreDataService::KvStoreClientDeathObserverImpl::~KvStoreClientDeathObserverImpl()
558 {
559     ZLOGI("~KvStoreClientDeathObserverImpl");
560     if (deathRecipient_ != nullptr && observerProxy_ != nullptr) {
561         ZLOGI("remove death recipient");
562         observerProxy_->RemoveDeathRecipient(deathRecipient_);
563     }
564     dataService_.features_.ForEachCopies([this](const auto &, sptr<DistributedData::FeatureStubImpl> &value) {
565         value->OnAppExit(uid_, pid_, token_, appId_);
566         return false;
567     });
568 }
569 
NotifyClientDie()570 void KvStoreDataService::KvStoreClientDeathObserverImpl::NotifyClientDie()
571 {
572     ZLOGI("appId: %{public}s uid:%{public}d tokenId:%{public}u", appId_.appId.c_str(), uid_, token_);
573     dataService_.AppExit(uid_, pid_, token_, appId_);
574 }
575 
GetPid() const576 pid_t KvStoreDataService::KvStoreClientDeathObserverImpl::GetPid() const
577 {
578     return pid_;
579 }
580 
KvStoreDeathRecipient(KvStoreClientDeathObserverImpl & kvStoreClientDeathObserverImpl)581 KvStoreDataService::KvStoreClientDeathObserverImpl::KvStoreDeathRecipient::KvStoreDeathRecipient(
582     KvStoreClientDeathObserverImpl &kvStoreClientDeathObserverImpl)
583     : kvStoreClientDeathObserverImpl_(kvStoreClientDeathObserverImpl)
584 {
585     ZLOGI("KvStore Client Death Observer");
586 }
587 
~KvStoreDeathRecipient()588 KvStoreDataService::KvStoreClientDeathObserverImpl::KvStoreDeathRecipient::~KvStoreDeathRecipient()
589 {
590     ZLOGD("~KvStore Client Death Observer");
591 }
592 
OnRemoteDied(const wptr<IRemoteObject> & remote)593 void KvStoreDataService::KvStoreClientDeathObserverImpl::KvStoreDeathRecipient::OnRemoteDied(
594     const wptr<IRemoteObject> &remote)
595 {
596     (void) remote;
597     ZLOGI("begin");
598     kvStoreClientDeathObserverImpl_.NotifyClientDie();
599 }
600 
AccountEventChanged(const AccountEventInfo & eventInfo)601 void KvStoreDataService::AccountEventChanged(const AccountEventInfo &eventInfo)
602 {
603     ZLOGI("account event %{public}d changed process, begin.", eventInfo.status);
604     NotifyAccountEvent(eventInfo);
605     switch (eventInfo.status) {
606         case AccountStatus::DEVICE_ACCOUNT_DELETE: {
607             g_kvStoreAccountEventStatus = 1;
608             // delete all kvstore meta belong to this user
609             std::vector<StoreMetaData> metaData;
610             MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({""}), metaData, true);
611             for (const auto &meta : metaData) {
612                 if (meta.user != eventInfo.userId) {
613                     continue;
614                 }
615                 ZLOGI("bundleName:%{public}s, user:%{public}s", meta.bundleName.c_str(), meta.user.c_str());
616                 MetaDataManager::GetInstance().DelMeta(meta.GetKey());
617                 MetaDataManager::GetInstance().DelMeta(meta.GetKey(), true);
618                 MetaDataManager::GetInstance().DelMeta(meta.GetStrategyKey());
619                 MetaDataManager::GetInstance().DelMeta(meta.GetSecretKey(), true);
620                 MetaDataManager::GetInstance().DelMeta(meta.appId, true);
621                 MetaDataManager::GetInstance().DelMeta(meta.GetKeyLocal(), true);
622                 PermitDelegate::GetInstance().DelCache(meta.GetKey());
623             }
624             g_kvStoreAccountEventStatus = 0;
625             break;
626         }
627         case AccountStatus::DEVICE_ACCOUNT_SWITCHED: {
628             auto ret = DistributedDB::KvStoreDelegateManager::NotifyUserChanged();
629             ZLOGI("notify delegate manager result:%{public}d", ret);
630             break;
631         }
632         default: {
633             break;
634         }
635     }
636     ZLOGI("account event %{public}d changed process, end.", eventInfo.status);
637 }
638 
NotifyAccountEvent(const AccountEventInfo & eventInfo)639 void KvStoreDataService::NotifyAccountEvent(const AccountEventInfo &eventInfo)
640 {
641     features_.ForEachCopies([&eventInfo](const auto &key, sptr<DistributedData::FeatureStubImpl> &value) {
642         value->OnUserChange(uint32_t(eventInfo.status), eventInfo.userId, eventInfo.harmonyAccountId);
643         return false;
644     });
645 }
646 
InitSecurityAdapter(std::shared_ptr<ExecutorPool> executors)647 void KvStoreDataService::InitSecurityAdapter(std::shared_ptr<ExecutorPool> executors)
648 {
649     auto ret = DATASL_OnStart();
650     ZLOGI("datasl on start ret:%d", ret);
651     security_ = std::make_shared<Security>(executors);
652     if (security_ == nullptr) {
653         ZLOGE("security is nullptr.");
654         return;
655     }
656 
657     auto dbStatus = DistributedDB::RuntimeConfig::SetProcessSystemAPIAdapter(security_);
658     ZLOGD("set distributed db system api adapter: %d.", static_cast<int>(dbStatus));
659 
660     auto status = DmAdapter::GetInstance().StartWatchDeviceChange(security_.get(), {"security"});
661     if (status != Status::SUCCESS) {
662         ZLOGD("security register device change failed, status:%d", static_cast<int>(status));
663     }
664 }
665 
SetCompatibleIdentify(const AppDistributedKv::DeviceInfo & info) const666 void KvStoreDataService::SetCompatibleIdentify(const AppDistributedKv::DeviceInfo &info) const
667 {
668 }
669 
OnDeviceOnline(const AppDistributedKv::DeviceInfo & info)670 void KvStoreDataService::OnDeviceOnline(const AppDistributedKv::DeviceInfo &info)
671 {
672     if (info.uuid.empty()) {
673         return;
674     }
675     features_.ForEachCopies([&info](const auto &key, sptr<DistributedData::FeatureStubImpl> &value) {
676         value->Online(info.uuid);
677         return false;
678     });
679 }
680 
OnDeviceOffline(const AppDistributedKv::DeviceInfo & info)681 void KvStoreDataService::OnDeviceOffline(const AppDistributedKv::DeviceInfo &info)
682 {
683     if (info.uuid.empty()) {
684         return;
685     }
686     features_.ForEachCopies([&info](const auto &key, sptr<DistributedData::FeatureStubImpl> &value) {
687         value->Offline(info.uuid);
688         return false;
689     });
690 }
691 
OnDeviceOnReady(const AppDistributedKv::DeviceInfo & info)692 void KvStoreDataService::OnDeviceOnReady(const AppDistributedKv::DeviceInfo &info)
693 {
694     if (info.uuid.empty()) {
695         return;
696     }
697     features_.ForEachCopies([&info](const auto &key, sptr<DistributedData::FeatureStubImpl> &value) {
698         value->OnReady(info.uuid);
699         return false;
700     });
701 }
702 
OnUninstall(const std::string & bundleName,int32_t user,int32_t index)703 int32_t KvStoreDataService::OnUninstall(const std::string &bundleName, int32_t user, int32_t index)
704 {
705     auto staticActs = FeatureSystem::GetInstance().GetStaticActs();
706     staticActs.ForEachCopies([bundleName, user, index](const auto &, const std::shared_ptr<StaticActs>& acts) {
707         acts->OnAppUninstall(bundleName, user, index);
708         return false;
709     });
710     return SUCCESS;
711 }
712 
OnUpdate(const std::string & bundleName,int32_t user,int32_t index)713 int32_t KvStoreDataService::OnUpdate(const std::string &bundleName, int32_t user, int32_t index)
714 {
715     auto staticActs = FeatureSystem::GetInstance().GetStaticActs();
716     staticActs.ForEachCopies([bundleName, user, index](const auto &, const std::shared_ptr<StaticActs>& acts) {
717         acts->OnAppUpdate(bundleName, user, index);
718         return false;
719     });
720     return SUCCESS;
721 }
722 
OnInstall(const std::string & bundleName,int32_t user,int32_t index)723 int32_t KvStoreDataService::OnInstall(const std::string &bundleName, int32_t user, int32_t index)
724 {
725     auto staticActs = FeatureSystem::GetInstance().GetStaticActs();
726     staticActs.ForEachCopies([bundleName, user, index](const auto &, const std::shared_ptr<StaticActs>& acts) {
727         acts->OnAppInstall(bundleName, user, index);
728         return false;
729     });
730     return SUCCESS;
731 }
732 
ClearAppStorage(const std::string & bundleName,int32_t userId,int32_t appIndex,int32_t tokenId)733 int32_t KvStoreDataService::ClearAppStorage(const std::string &bundleName, int32_t userId, int32_t appIndex,
734     int32_t tokenId)
735 {
736     HapTokenInfo hapTokenInfo;
737     if (AccessTokenKit::GetHapTokenInfo(tokenId, hapTokenInfo) != RET_SUCCESS ||
738         hapTokenInfo.bundleName != bundleName || hapTokenInfo.userID != userId ||
739         hapTokenInfo.instIndex != appIndex) {
740         ZLOGE("passed wrong, tokenId: %{public}u, bundleName:%{public}s, user:%{public}d, appIndex:%{public}d",
741             tokenId, bundleName.c_str(), userId, appIndex);
742         return ERROR;
743     }
744 
745     auto staticActs = FeatureSystem::GetInstance().GetStaticActs();
746     staticActs.ForEachCopies(
747         [bundleName, userId, appIndex, tokenId](const auto &, const std::shared_ptr<StaticActs> &acts) {
748             acts->OnClearAppStorage(bundleName, userId, appIndex, tokenId);
749             return false;
750         });
751 
752     std::vector<StoreMetaData> metaData;
753     std::string prefix = StoreMetaData::GetPrefix(
754         { DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid, std::to_string(userId), "default", bundleName });
755     if (!MetaDataManager::GetInstance().LoadMeta(prefix, metaData, true)) {
756         ZLOGE("Clear data load meta failed, bundleName:%{public}s, user:%{public}d, appIndex:%{public}d",
757             bundleName.c_str(), userId, appIndex);
758         return ERROR;
759     }
760 
761     for (auto &meta : metaData) {
762         if (meta.instanceId == appIndex && !meta.appId.empty() && !meta.storeId.empty()) {
763             ZLOGI("data cleared bundleName:%{public}s, stordId:%{public}s, appIndex:%{public}d", bundleName.c_str(),
764                 Anonymous::Change(meta.storeId).c_str(), appIndex);
765             MetaDataManager::GetInstance().DelMeta(meta.GetKey());
766             MetaDataManager::GetInstance().DelMeta(meta.GetKey(), true);
767             MetaDataManager::GetInstance().DelMeta(meta.GetSecretKey(), true);
768             MetaDataManager::GetInstance().DelMeta(meta.GetStrategyKey());
769             MetaDataManager::GetInstance().DelMeta(meta.appId, true);
770             MetaDataManager::GetInstance().DelMeta(meta.GetKeyLocal(), true);
771             PermitDelegate::GetInstance().DelCache(meta.GetKey());
772         }
773     }
774     return SUCCESS;
775 }
776 
RegisterStoreInfo()777 void KvStoreDataService::RegisterStoreInfo()
778 {
779     OHOS::DistributedData::DumpManager::Config storeInfoConfig;
780     storeInfoConfig.fullCmd = "--store-info";
781     storeInfoConfig.abbrCmd = "-s";
782     storeInfoConfig.dumpName = "STORE_INFO";
783     storeInfoConfig.countPrintf = PRINTF_COUNT_2;
784     storeInfoConfig.infoName = " <StoreId>";
785     storeInfoConfig.minParamsNum = 0;
786     storeInfoConfig.maxParamsNum = MAXIMUM_PARAMETER_LIMIT; // Store contains no more than three parameters
787     storeInfoConfig.parentNode = "BUNDLE_INFO";
788     storeInfoConfig.dumpCaption = { "| Display all the store statistics", "| Display the store statistics  by "
789                                                                           "StoreID" };
790     DumpManager::GetInstance().AddConfig(storeInfoConfig.dumpName, storeInfoConfig);
791 }
792 
DumpStoreInfo(int fd,std::map<std::string,std::vector<std::string>> & params)793 void KvStoreDataService::DumpStoreInfo(int fd, std::map<std::string, std::vector<std::string>> &params)
794 {
795     std::vector<StoreMetaData> metas;
796     std::string localDeviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
797     if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ localDeviceId }), metas, true)) {
798         ZLOGE("get full meta failed");
799         return;
800     }
801     FilterData(metas, params);
802     PrintfInfo(fd, metas);
803 }
804 
FilterData(std::vector<StoreMetaData> & metas,std::map<std::string,std::vector<std::string>> & filterInfo)805 void KvStoreDataService::FilterData(std::vector<StoreMetaData> &metas,
806     std::map<std::string, std::vector<std::string>> &filterInfo)
807 {
808     for (auto iter = metas.begin(); iter != metas.end();) {
809         if ((IsExist("USER_INFO", filterInfo, iter->user)) || (IsExist("BUNDLE_INFO", filterInfo, iter->bundleName)) ||
810             (IsExist("STORE_INFO", filterInfo, iter->storeId))) {
811             iter = metas.erase(iter);
812         } else {
813             iter++;
814         }
815     }
816 }
817 
IsExist(const std::string & infoName,std::map<std::string,std::vector<std::string>> & filterInfo,std::string & metaParam)818 bool KvStoreDataService::IsExist(const std::string &infoName,
819     std::map<std::string, std::vector<std::string>> &filterInfo, std::string &metaParam)
820 {
821     auto info = filterInfo.find(infoName);
822     if (info != filterInfo.end()) {
823         if (!info->second.empty()) {
824             auto it = find(info->second.begin(), info->second.end(), metaParam);
825             if (it == info->second.end()) {
826                 return true;
827             }
828         }
829     }
830     return false;
831 }
832 
PrintfInfo(int fd,const std::vector<StoreMetaData> & metas)833 void KvStoreDataService::PrintfInfo(int fd, const std::vector<StoreMetaData> &metas)
834 {
835     std::string info;
836     int indentation = 0;
837     if (metas.size() > 1) {
838         info.append("Stores: ").append(std::to_string(metas.size())).append("\n");
839         indentation++;
840     }
841     for (auto &data : metas) {
842         char version[VERSION_WIDTH];
843         auto flag = sprintf_s(version, sizeof(version), "0x%08X", data.version);
844         if (flag < 0) {
845             ZLOGE("get version failed");
846             return;
847         }
848         info.append(GetIndentation(indentation))
849             .append("--------------------------------------------------------------------------\n")
850             .append(GetIndentation(indentation)).append("StoreID           : ").append(data.storeId).append("\n")
851             .append(GetIndentation(indentation)).append("UId               : ").append(data.user).append("\n")
852             .append(GetIndentation(indentation)).append("BundleName        : ").append(data.bundleName).append("\n")
853             .append(GetIndentation(indentation)).append("AppID             : ").append(data.appId).append("\n")
854             .append(GetIndentation(indentation)).append("StorePath         : ").append(data.dataDir).append("\n")
855             .append(GetIndentation(indentation)).append("StoreType         : ")
856             .append(std::to_string(data.storeType)).append("\n")
857             .append(GetIndentation(indentation)).append("encrypt           : ")
858             .append(std::to_string(data.isEncrypt)).append("\n")
859             .append(GetIndentation(indentation)).append("autoSync          : ")
860             .append(std::to_string(data.isAutoSync)).append("\n")
861             .append(GetIndentation(indentation)).append("schema            : ").append(data.schema).append("\n")
862             .append(GetIndentation(indentation)).append("securityLevel     : ")
863             .append(std::to_string(data.securityLevel)).append("\n")
864             .append(GetIndentation(indentation)).append("area              : ")
865             .append(std::to_string(data.area)).append("\n")
866             .append(GetIndentation(indentation)).append("instanceID        : ")
867             .append(std::to_string(data.instanceId)).append("\n")
868             .append(GetIndentation(indentation)).append("version           : ").append(version).append("\n");
869     }
870     dprintf(fd, "--------------------------------------StoreInfo-------------------------------------\n%s\n",
871         info.c_str());
872 }
873 
GetIndentation(int size)874 std::string KvStoreDataService::GetIndentation(int size)
875 {
876     std::string indentation;
877     for (int i = 0; i < size; i++) {
878         indentation.append(INDENTATION);
879     }
880     return indentation;
881 }
882 
RegisterUserInfo()883 void KvStoreDataService::RegisterUserInfo()
884 {
885     DumpManager::Config userInfoConfig;
886     userInfoConfig.fullCmd = "--user-info";
887     userInfoConfig.abbrCmd = "-u";
888     userInfoConfig.dumpName = "USER_INFO";
889     userInfoConfig.countPrintf = PRINTF_COUNT_2;
890     userInfoConfig.infoName = " <UId>";
891     userInfoConfig.minParamsNum = 0;
892     userInfoConfig.maxParamsNum = MAXIMUM_PARAMETER_LIMIT; // User contains no more than three parameters
893     userInfoConfig.childNode = "BUNDLE_INFO";
894     userInfoConfig.dumpCaption = { "| Display all the user statistics", "| Display the user statistics by UserId" };
895     DumpManager::GetInstance().AddConfig(userInfoConfig.dumpName, userInfoConfig);
896 }
897 
BuildData(std::map<std::string,UserInfo> & datas,const std::vector<StoreMetaData> & metas)898 void KvStoreDataService::BuildData(std::map<std::string, UserInfo> &datas, const std::vector<StoreMetaData> &metas)
899 {
900     for (auto &meta : metas) {
901         auto it = datas.find(meta.user);
902         if (it == datas.end()) {
903             UserInfo userInfo;
904             userInfo.userId = meta.user;
905             userInfo.bundles.insert(meta.bundleName);
906             datas[meta.user] = userInfo;
907         } else {
908             std::set<std::string> bundles_ = datas[meta.user].bundles;
909             auto iter = std::find(bundles_.begin(), bundles_.end(), meta.bundleName);
910             if (iter == bundles_.end()) {
911                 datas[meta.user].bundles.insert(meta.bundleName);
912             }
913         }
914     }
915 }
916 
PrintfInfo(int fd,const std::map<std::string,UserInfo> & datas)917 void KvStoreDataService::PrintfInfo(int fd, const std::map<std::string, UserInfo> &datas)
918 {
919     std::string info;
920     int indentation = 0;
921     if (datas.size() > 1) {
922         info.append("Users : ").append(std::to_string(datas.size())).append("\n");
923         indentation++;
924     }
925 
926     for (auto &data : datas) {
927         info.append(GetIndentation(indentation))
928             .append("------------------------------------------------------------------------------\n")
929             .append("UID        : ")
930             .append(data.second.userId)
931             .append("\n");
932         info.append(GetIndentation(indentation))
933             .append("Bundles       : ")
934             .append(std::to_string(data.second.bundles.size()))
935             .append("\n");
936         indentation++;
937         info.append("------------------------------------------------------------------------------\n");
938         for (auto &bundle : data.second.bundles) {
939             info.append(GetIndentation(indentation)).append("BundleName    : ").append(bundle).append("\n");
940         }
941         indentation--;
942     }
943     dprintf(fd, "--------------------------------------UserInfo--------------------------------------\n%s\n",
944         info.c_str());
945 }
946 
DumpUserInfo(int fd,std::map<std::string,std::vector<std::string>> & params)947 void KvStoreDataService::DumpUserInfo(int fd, std::map<std::string, std::vector<std::string>> &params)
948 {
949     std::vector<StoreMetaData> metas;
950     std::string localDeviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
951     if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ localDeviceId }), metas, true)) {
952         ZLOGE("get full meta failed");
953         return;
954     }
955     FilterData(metas, params);
956     std::map<std::string, UserInfo> datas;
957     BuildData(datas, metas);
958     PrintfInfo(fd, datas);
959 }
960 
RegisterBundleInfo()961 void KvStoreDataService::RegisterBundleInfo()
962 {
963     DumpManager::Config bundleInfoConfig;
964     bundleInfoConfig.fullCmd = "--bundle-info";
965     bundleInfoConfig.abbrCmd = "-b";
966     bundleInfoConfig.dumpName = "BUNDLE_INFO";
967     bundleInfoConfig.countPrintf = PRINTF_COUNT_2;
968     bundleInfoConfig.infoName = " <BundleName>";
969     bundleInfoConfig.minParamsNum = 0;
970     bundleInfoConfig.maxParamsNum = MAXIMUM_PARAMETER_LIMIT; // Bundle contains no more than three parameters
971     bundleInfoConfig.parentNode = "USER_INFO";
972     bundleInfoConfig.childNode = "STORE_INFO";
973     bundleInfoConfig.dumpCaption = { "| Display all the bundle statistics", "| Display the bundle statistics by "
974                                                                             "BundleName" };
975     DumpManager::GetInstance().AddConfig(bundleInfoConfig.dumpName, bundleInfoConfig);
976 }
977 
BuildData(std::map<std::string,BundleInfo> & datas,const std::vector<StoreMetaData> & metas)978 void KvStoreDataService::BuildData(std::map<std::string, BundleInfo> &datas, const std::vector<StoreMetaData> &metas)
979 {
980     for (auto &meta : metas) {
981         auto it = datas.find(meta.bundleName);
982         if (it == datas.end()) {
983             BundleInfo bundleInfo;
984             bundleInfo.bundleName = meta.bundleName;
985             bundleInfo.appId = meta.appId;
986             bundleInfo.type = meta.appType;
987             bundleInfo.uid = meta.uid;
988             bundleInfo.tokenId = meta.tokenId;
989             bundleInfo.userId = meta.user;
990             std::string storeId = meta.storeId;
991             storeId.resize(FORMAT_BLANK_SIZE, FORMAT_BLANK_SPACE);
992             bundleInfo.storeIDs.insert(storeId);
993             datas[meta.bundleName] = bundleInfo;
994         } else {
995             std::set<std::string> storeIDs_ = datas[meta.bundleName].storeIDs;
996             std::string storeId = meta.storeId;
997             storeId.resize(FORMAT_BLANK_SIZE, FORMAT_BLANK_SPACE);
998             auto iter = std::find(storeIDs_.begin(), storeIDs_.end(), storeId);
999             if (iter == storeIDs_.end()) {
1000                 datas[meta.bundleName].storeIDs.insert(storeId);
1001             }
1002         }
1003     }
1004 }
1005 
PrintfInfo(int fd,const std::map<std::string,BundleInfo> & datas)1006 void KvStoreDataService::PrintfInfo(int fd, const std::map<std::string, BundleInfo> &datas)
1007 {
1008     std::string info;
1009     int indentation = 0;
1010     if (datas.size() > 1) {
1011         info.append("Bundles: ").append(std::to_string(datas.size())).append("\n");
1012         indentation++;
1013     }
1014     for (auto &data : datas) {
1015         info.append(GetIndentation(indentation))
1016             .append("--------------------------------------------------------------------------\n");
1017         info.append(GetIndentation(indentation)).append("BundleName     : ")
1018             .append(data.second.bundleName).append("\n");
1019         info.append(GetIndentation(indentation)).append("AppID          : ")
1020             .append(data.second.appId).append("\n");
1021         info.append(GetIndentation(indentation)).append("Type           : ")
1022             .append(data.second.type).append("\n");
1023         info.append(GetIndentation(indentation))
1024             .append("UId            : ")
1025             .append(std::to_string(data.second.uid))
1026             .append("\n");
1027         info.append(GetIndentation(indentation))
1028             .append("TokenID        : ")
1029             .append(std::to_string(data.second.tokenId))
1030             .append("\n");
1031         info.append(GetIndentation(indentation)).append("UserID         : ").append(data.second.userId).append("\n");
1032         info.append(GetIndentation(indentation))
1033             .append("Stores         : ")
1034             .append(std::to_string(data.second.storeIDs.size()))
1035             .append("\n");
1036         indentation++;
1037         info.append("----------------------------------------------------------------------\n");
1038         for (auto &store : data.second.storeIDs) {
1039             info.append(GetIndentation(indentation)).append("StoreID    : ").append(store).append("\n");
1040         }
1041         indentation--;
1042     }
1043     dprintf(fd, "-------------------------------------BundleInfo-------------------------------------\n%s\n",
1044         info.c_str());
1045 }
1046 
DumpBundleInfo(int fd,std::map<std::string,std::vector<std::string>> & params)1047 void KvStoreDataService::DumpBundleInfo(int fd, std::map<std::string, std::vector<std::string>> &params)
1048 {
1049     std::vector<StoreMetaData> metas;
1050     std::string localDeviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
1051     if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ localDeviceId }), metas, true)) {
1052         ZLOGE("get full meta failed");
1053         return;
1054     }
1055     FilterData(metas, params);
1056     std::map<std::string, BundleInfo> datas;
1057     BuildData(datas, metas);
1058     PrintfInfo(fd, datas);
1059 }
1060 } // namespace OHOS::DistributedKv
1061