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