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