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 ¶m) -> bool {
345 auto status = ResolveAutoLaunchParamByIdentifier(identifier, param);
346 features_.ForEachCopies([&identifier, ¶m](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 ¶m)
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>> ¶ms)
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>> ¶ms)
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>> ¶ms)
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