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 "auth_delegate.h"
23 #include "auto_launch_export.h"
24 #include "bootstrap.h"
25 #include "checker/checker_manager.h"
26 #include "communication_provider.h"
27 #include "communicator_context.h"
28 #include "config_factory.h"
29 #include "crypto_manager.h"
30 #include "device_manager_adapter.h"
31 #include "device_matrix.h"
32 #include "eventcenter/event_center.h"
33 #include "if_system_ability_manager.h"
34 #include "iservice_registry.h"
35 #include "kvstore_account_observer.h"
36 #include "log_print.h"
37 #include "metadata/appid_meta_data.h"
38 #include "metadata/meta_data_manager.h"
39 #include "metadata/secret_key_meta_data.h"
40 #include "permission_validator.h"
41 #include "permit_delegate.h"
42 #include "process_communicator_impl.h"
43 #include "reporter.h"
44 #include "route_head_handler_impl.h"
45 #include "runtime_config.h"
46 #include "string_ex.h"
47 #include "system_ability_definition.h"
48 #include "task_manager.h"
49 #include "uninstaller/uninstaller.h"
50 #include "upgrade.h"
51 #include "upgrade_manager.h"
52 #include "user_delegate.h"
53 #include "utils/anonymous.h"
54 #include "utils/block_integer.h"
55 #include "utils/crypto.h"
56
57 namespace OHOS::DistributedKv {
58 using namespace std::chrono;
59 using namespace OHOS::DistributedData;
60 using namespace OHOS::DistributedDataDfx;
61 using KvStoreDelegateManager = DistributedDB::KvStoreDelegateManager;
62 using SecretKeyMeta = DistributedData::SecretKeyMetaData;
63 using DmAdapter = DistributedData::DeviceManagerAdapter;
64 using DBConfig = DistributedDB::RuntimeConfig;
65
66 REGISTER_SYSTEM_ABILITY_BY_ID(KvStoreDataService, DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID, true);
67
KvStoreDataService(bool runOnCreate)68 KvStoreDataService::KvStoreDataService(bool runOnCreate)
69 : SystemAbility(runOnCreate), mutex_(), clients_()
70 {
71 ZLOGI("begin.");
72 if (executors_ == nullptr) {
73 constexpr size_t MAX = 12;
74 constexpr size_t MIN = 5;
75 executors_ = std::make_shared<ExecutorPool>(MAX, MIN);
76 DistributedDB::RuntimeConfig::SetThreadPool(std::make_shared<TaskManager>(executors_));
77 }
78 }
79
KvStoreDataService(int32_t systemAbilityId,bool runOnCreate)80 KvStoreDataService::KvStoreDataService(int32_t systemAbilityId, bool runOnCreate)
81 : SystemAbility(systemAbilityId, runOnCreate), mutex_(), clients_()
82 {
83 ZLOGI("begin");
84 if (executors_ == nullptr) {
85 constexpr size_t MAX = 12;
86 constexpr size_t MIN = 5;
87 executors_ = std::make_shared<ExecutorPool>(MAX, MIN);
88 DistributedDB::RuntimeConfig::SetThreadPool(std::make_shared<TaskManager>(executors_));
89 }
90 }
91
~KvStoreDataService()92 KvStoreDataService::~KvStoreDataService()
93 {
94 ZLOGI("begin.");
95 clients_.clear();
96 features_.Clear();
97 }
98
Initialize()99 void KvStoreDataService::Initialize()
100 {
101 ZLOGI("begin.");
102 #ifndef UT_TEST
103 KvStoreDelegateManager::SetProcessLabel(Bootstrap::GetInstance().GetProcessLabel(), "default");
104 #endif
105 CommunicatorContext::getInstance().SetThreadPool(executors_);
106 auto communicator = std::make_shared<AppDistributedKv::ProcessCommunicatorImpl>(RouteHeadHandlerImpl::Create);
107 auto ret = KvStoreDelegateManager::SetProcessCommunicator(communicator);
108 ZLOGI("set communicator ret:%{public}d.", static_cast<int>(ret));
109
110 AppDistributedKv::CommunicationProvider::GetInstance();
111 PermitDelegate::GetInstance().Init();
112 InitSecurityAdapter(executors_);
113 KvStoreMetaManager::GetInstance().BindExecutor(executors_);
114 KvStoreMetaManager::GetInstance().InitMetaParameter();
115 accountEventObserver_ = std::make_shared<KvStoreAccountObserver>(*this, executors_);
116 AccountDelegate::GetInstance()->Subscribe(accountEventObserver_);
117 deviceInnerListener_ = std::make_unique<KvStoreDeviceListener>(*this);
118 DmAdapter::GetInstance().StartWatchDeviceChange(deviceInnerListener_.get(), { "innerListener" });
119 auto translateCall = [](const std::string &oriDevId, const DistributedDB::StoreInfo &info) {
120 StoreMetaData meta;
121 AppIDMetaData appIdMeta;
122 MetaDataManager::GetInstance().LoadMeta(info.appId, appIdMeta, true);
123 meta.bundleName = appIdMeta.bundleName;
124 meta.storeId = info.storeId;
125 meta.user = info.userId;
126 meta.deviceId = oriDevId;
127 MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta);
128 return Upgrade::GetInstance().GetEncryptedUuidByMeta(meta);
129 };
130 DBConfig::SetTranslateToDeviceIdCallback(translateCall);
131 }
132
GetFeatureInterface(const std::string & name)133 sptr<IRemoteObject> KvStoreDataService::GetFeatureInterface(const std::string &name)
134 {
135 sptr<FeatureStubImpl> feature;
136 bool isFirstCreate = false;
137 features_.Compute(name, [&feature, &isFirstCreate](const auto &key, auto &value) ->bool {
138 if (value != nullptr) {
139 feature = value;
140 return true;
141 }
142 auto creator = FeatureSystem::GetInstance().GetCreator(key);
143 if (!creator) {
144 return false;
145 }
146 auto impl = creator();
147 if (impl == nullptr) {
148 return false;
149 }
150
151 value = new FeatureStubImpl(impl);
152 feature = value;
153 isFirstCreate = true;
154 return true;
155 });
156 if (isFirstCreate) {
157 feature->OnInitialize(executors_);
158 }
159 return feature != nullptr ? feature->AsObject() : nullptr;
160 }
161
LoadFeatures()162 void KvStoreDataService::LoadFeatures()
163 {
164 ZLOGI("begin.");
165 auto features = FeatureSystem::GetInstance().GetFeatureName(FeatureSystem::BIND_NOW);
166 for (auto const &feature : features) {
167 GetFeatureInterface(feature);
168 }
169 }
170
171 /* RegisterClientDeathObserver */
RegisterClientDeathObserver(const AppId & appId,sptr<IRemoteObject> observer)172 Status KvStoreDataService::RegisterClientDeathObserver(const AppId &appId, sptr<IRemoteObject> observer)
173 {
174 ZLOGD("begin.");
175 KVSTORE_ACCOUNT_EVENT_PROCESSING_CHECKER(Status::SYSTEM_ACCOUNT_EVENT_PROCESSING);
176 if (!appId.IsValid()) {
177 ZLOGE("invalid bundleName, name:%{public}s", appId.appId.c_str());
178 return Status::INVALID_ARGUMENT;
179 }
180
181 CheckerManager::StoreInfo info;
182 info.uid = IPCSkeleton::GetCallingUid();
183 info.tokenId = IPCSkeleton::GetCallingTokenID();
184 info.bundleName = appId.appId;
185 info.storeId = "";
186 if (!CheckerManager::GetInstance().IsValid(info)) {
187 ZLOGW("check bundleName:%{public}s uid:%{public}d failed.", appId.appId.c_str(), info.uid);
188 return Status::PERMISSION_DENIED;
189 }
190
191 std::lock_guard<decltype(mutex_)> lg(mutex_);
192 auto iter = clients_.find(info.tokenId);
193 // Ignore register with same tokenId and pid
194 if (iter != clients_.end() && IPCSkeleton::GetCallingPid() == iter->second.GetPid()) {
195 ZLOGW("bundleName:%{public}s, uid:%{public}d, pid:%{public}d has already registered.",
196 appId.appId.c_str(), info.uid, IPCSkeleton::GetCallingPid());
197 return Status::SUCCESS;
198 }
199
200 clients_.erase(info.tokenId);
201 auto it = clients_.emplace(std::piecewise_construct, std::forward_as_tuple(info.tokenId),
202 std::forward_as_tuple(appId, *this, std::move(observer)));
203 ZLOGI("bundleName:%{public}s, uid:%{public}d, pid:%{public}d inserted:%{public}s.",
204 appId.appId.c_str(), info.uid, IPCSkeleton::GetCallingPid(), it.second ? "success" : "failed");
205 return it.second ? Status::SUCCESS : Status::ERROR;
206 }
207
AppExit(pid_t uid,pid_t pid,uint32_t token,const AppId & appId)208 Status KvStoreDataService::AppExit(pid_t uid, pid_t pid, uint32_t token, const AppId &appId)
209 {
210 ZLOGI("AppExit");
211 // memory of parameter appId locates in a member of clientDeathObserverMap_ and will be freed after
212 // clientDeathObserverMap_ erase, so we have to take a copy if we want to use this parameter after erase operation.
213 AppId appIdTmp = appId;
214 std::lock_guard<decltype(mutex_)> lg(mutex_);
215 clients_.erase(token);
216 return Status::SUCCESS;
217 }
218
OnDump()219 void KvStoreDataService::OnDump()
220 {
221 ZLOGD("begin.");
222 }
223
Dump(int fd,const std::vector<std::u16string> & args)224 int KvStoreDataService::Dump(int fd, const std::vector<std::u16string> &args)
225 {
226 int uid = static_cast<int>(IPCSkeleton::GetCallingUid());
227 const int maxUid = 10000;
228 if (uid > maxUid) {
229 return 0;
230 }
231
232 std::vector<std::string> argsStr;
233 for (auto item : args) {
234 argsStr.emplace_back(Str16ToStr8(item));
235 }
236
237 if (DumpHelper::GetInstance().Dump(fd, argsStr)) {
238 return 0;
239 }
240
241 ZLOGE("DumpHelper failed");
242 return ERROR;
243 }
244
OnStart()245 void KvStoreDataService::OnStart()
246 {
247 ZLOGI("distributeddata service onStart");
248 EventCenter::Defer defer;
249 Reporter::GetInstance()->SetThreadPool(executors_);
250 AccountDelegate::GetInstance()->BindExecutor(executors_);
251 AccountDelegate::GetInstance()->RegisterHashFunc(Crypto::Sha256);
252 DmAdapter::GetInstance().Init(executors_);
253 static constexpr int32_t RETRY_TIMES = 50;
254 static constexpr int32_t RETRY_INTERVAL = 500 * 1000; // unit is ms
255 for (BlockInteger retry(RETRY_INTERVAL); retry < RETRY_TIMES; ++retry) {
256 if (!DmAdapter::GetInstance().GetLocalDevice().uuid.empty()) {
257 break;
258 }
259 ZLOGW("GetLocalDeviceId failed, retry count:%{public}d", static_cast<int>(retry));
260 }
261 ZLOGI("Bootstrap configs and plugins.");
262 Bootstrap::GetInstance().LoadComponents();
263 Bootstrap::GetInstance().LoadDirectory();
264 Bootstrap::GetInstance().LoadCheckers();
265 Bootstrap::GetInstance().LoadNetworks();
266 Bootstrap::GetInstance().LoadBackup(executors_);
267 Initialize();
268 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
269 if (samgr != nullptr) {
270 ZLOGI("samgr exist.");
271 auto remote = samgr->CheckSystemAbility(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID);
272 auto kvDataServiceProxy = iface_cast<IKvStoreDataService>(remote);
273 if (kvDataServiceProxy != nullptr) {
274 ZLOGI("service has been registered.");
275 return;
276 }
277 }
278 AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
279 StartService();
280 }
281
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)282 void KvStoreDataService::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
283 {
284 ZLOGI("add system abilityid:%{public}d", systemAbilityId);
285 (void)deviceId;
286 if (systemAbilityId != COMMON_EVENT_SERVICE_ID) {
287 return;
288 }
289 AccountDelegate::GetInstance()->SubscribeAccountEvent();
290 Uninstaller::GetInstance().Init(this, executors_);
291 }
292
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)293 void KvStoreDataService::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
294 {
295 ZLOGI("remove system abilityid:%{public}d", systemAbilityId);
296 (void)deviceId;
297 if (systemAbilityId != COMMON_EVENT_SERVICE_ID) {
298 return;
299 }
300 AccountDelegate::GetInstance()->UnsubscribeAccountEvent();
301 Uninstaller::GetInstance().UnsubscribeEvent();
302 }
303
StartService()304 void KvStoreDataService::StartService()
305 {
306 // register this to ServiceManager.
307 ZLOGI("begin.");
308 KvStoreMetaManager::GetInstance().InitMetaListener();
309 DeviceMatrix::GetInstance().Initialize(IPCSkeleton::GetCallingTokenID(), Bootstrap::GetInstance().GetMetaDBName());
310 LoadFeatures();
311 bool ret = SystemAbility::Publish(this);
312 if (!ret) {
313 DumpHelper::GetInstance().AddErrorInfo("StartService: Service publish failed.");
314 }
315 // Initialize meta db delegate manager.
316 KvStoreMetaManager::GetInstance().SubscribeMeta(StoreMetaData::GetKey({}),
317 [this](const std::vector<uint8_t> &key, const std::vector<uint8_t> &value, CHANGE_FLAG flag) {
318 OnStoreMetaChanged(key, value, flag);
319 });
320 UpgradeManager::GetInstance().Init(executors_);
321 UserDelegate::GetInstance().Init(executors_);
322
323 // subscribe account event listener to EventNotificationMgr
324 auto autoLaunch = [this](const std::string &identifier, DistributedDB::AutoLaunchParam ¶m) -> bool {
325 auto status = ResolveAutoLaunchParamByIdentifier(identifier, param);
326 features_.ForEachCopies([&identifier, ¶m](const auto &, sptr<DistributedData::FeatureStubImpl> &value) {
327 value->ResolveAutoLaunch(identifier, param);
328 return false;
329 });
330 return status;
331 };
332 KvStoreDelegateManager::SetAutoLaunchRequestCallback(autoLaunch);
333 ZLOGI("Publish ret: %{public}d", static_cast<int>(ret));
334 }
335
OnStoreMetaChanged(const std::vector<uint8_t> & key,const std::vector<uint8_t> & value,CHANGE_FLAG flag)336 void KvStoreDataService::OnStoreMetaChanged(
337 const std::vector<uint8_t> &key, const std::vector<uint8_t> &value, CHANGE_FLAG flag)
338 {
339 if (flag != CHANGE_FLAG::UPDATE) {
340 return;
341 }
342 StoreMetaData metaData;
343 metaData.Unmarshall({ value.begin(), value.end() });
344 ZLOGD("meta data info appType:%{public}s, storeId:%{public}s isDirty:%{public}d", metaData.appType.c_str(),
345 Anonymous::Change(metaData.storeId).c_str(), metaData.isDirty);
346 auto deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
347 if (metaData.deviceId != deviceId || metaData.deviceId.empty()) {
348 ZLOGD("ignore other device change or invalid meta device");
349 return;
350 }
351 static constexpr const char *HARMONY_APP = "harmony";
352 if (!metaData.isDirty || metaData.appType != HARMONY_APP) {
353 return;
354 }
355 ZLOGI("dirty kv store. storeId:%{public}s", Anonymous::Change(metaData.storeId).c_str());
356 }
357
ResolveAutoLaunchParamByIdentifier(const std::string & identifier,DistributedDB::AutoLaunchParam & param)358 bool KvStoreDataService::ResolveAutoLaunchParamByIdentifier(
359 const std::string &identifier, DistributedDB::AutoLaunchParam ¶m)
360 {
361 ZLOGI("start");
362 std::vector<StoreMetaData> entries;
363 std::string localDeviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
364 if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ localDeviceId }), entries)) {
365 ZLOGE("get full meta failed");
366 return false;
367 }
368
369 for (const auto &storeMeta : entries) {
370 if ((!param.userId.empty() && (param.userId != storeMeta.user)) || (localDeviceId != storeMeta.deviceId) ||
371 ((StoreMetaData::STORE_RELATIONAL_BEGIN <= storeMeta.storeType) &&
372 (StoreMetaData::STORE_RELATIONAL_END >= storeMeta.storeType))) {
373 // judge local userid and local meta
374 continue;
375 }
376 const std::string &itemTripleIdentifier =
377 DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(storeMeta.user, storeMeta.appId,
378 storeMeta.storeId, false);
379 const std::string &itemDualIdentifier =
380 DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier("", storeMeta.appId, storeMeta.storeId, true);
381 if (identifier == itemTripleIdentifier && storeMeta.bundleName != Bootstrap::GetInstance().GetProcessLabel()) {
382 // old triple tuple identifier, should SetEqualIdentifier
383 ResolveAutoLaunchCompatible(storeMeta, identifier);
384 }
385 if (identifier == itemDualIdentifier || identifier == itemTripleIdentifier) {
386 ZLOGI("identifier find");
387 DistributedDB::AutoLaunchOption option;
388 option.createIfNecessary = false;
389 option.isEncryptedDb = storeMeta.isEncrypt;
390
391 SecretKeyMeta secretKey;
392 if (storeMeta.isEncrypt && MetaDataManager::GetInstance().LoadMeta(storeMeta.GetSecretKey(), secretKey)) {
393 std::vector<uint8_t> decryptKey;
394 CryptoManager::GetInstance().Decrypt(secretKey.sKey, decryptKey);
395 option.passwd.SetValue(decryptKey.data(), decryptKey.size());
396 std::fill(decryptKey.begin(), decryptKey.end(), 0);
397 }
398
399 if (storeMeta.bundleName == Bootstrap::GetInstance().GetProcessLabel()) {
400 param.userId = storeMeta.user;
401 }
402 option.schema = storeMeta.schema;
403 option.createDirByStoreIdOnly = true;
404 option.dataDir = storeMeta.dataDir;
405 option.secOption = ConvertSecurity(storeMeta.securityLevel);
406 option.isAutoSync = storeMeta.isAutoSync;
407 option.syncDualTupleMode = true; // dual tuple flag
408 param.appId = storeMeta.appId;
409 param.storeId = storeMeta.storeId;
410 param.option = option;
411 return true;
412 }
413 }
414 ZLOGI("not find identifier");
415 return false;
416 }
417
ConvertSecurity(int securityLevel)418 DistributedDB::SecurityOption KvStoreDataService::ConvertSecurity(int securityLevel)
419 {
420 if (securityLevel < SecurityLevel::NO_LABEL || securityLevel > SecurityLevel::S4) {
421 return {DistributedDB::NOT_SET, DistributedDB::ECE};
422 }
423 switch (securityLevel) {
424 case SecurityLevel::S3:
425 return {DistributedDB::S3, DistributedDB::SECE};
426 case SecurityLevel::S4:
427 return {DistributedDB::S4, DistributedDB::ECE};
428 default:
429 return {securityLevel, DistributedDB::ECE};
430 }
431 }
432
ResolveAutoLaunchCompatible(const StoreMetaData & storeMeta,const std::string & identifier)433 void KvStoreDataService::ResolveAutoLaunchCompatible(const StoreMetaData &storeMeta, const std::string &identifier)
434 {
435 ZLOGI("AutoLaunch:peer device is old tuple, begin to open store");
436 if (storeMeta.storeType > KvStoreType::SINGLE_VERSION || storeMeta.version > STORE_VERSION) {
437 ZLOGW("no longer support multi or higher version store type");
438 return;
439 }
440
441 // open store and SetEqualIdentifier, then close store after 60s
442 DistributedDB::KvStoreDelegateManager delegateManager(storeMeta.appId, storeMeta.user);
443 delegateManager.SetKvStoreConfig({ storeMeta.dataDir });
444 Options options = {
445 .createIfMissing = false,
446 .encrypt = storeMeta.isEncrypt,
447 .autoSync = storeMeta.isAutoSync,
448 .securityLevel = storeMeta.securityLevel,
449 .kvStoreType = static_cast<KvStoreType>(storeMeta.storeType),
450 };
451 DistributedDB::KvStoreNbDelegate::Option dbOptions;
452 SecretKeyMeta secretKey;
453 if (storeMeta.isEncrypt && MetaDataManager::GetInstance().LoadMeta(storeMeta.GetSecretKey(), secretKey)) {
454 std::vector<uint8_t> decryptKey;
455 CryptoManager::GetInstance().Decrypt(secretKey.sKey, decryptKey);
456 std::fill(secretKey.sKey.begin(), secretKey.sKey.end(), 0);
457 secretKey.sKey = std::move(decryptKey);
458 std::fill(decryptKey.begin(), decryptKey.end(), 0);
459 }
460 InitNbDbOption(options, secretKey.sKey, dbOptions);
461 DistributedDB::KvStoreNbDelegate *store = nullptr;
462 delegateManager.GetKvStore(storeMeta.storeId, dbOptions,
463 [&store, &storeMeta](int status, DistributedDB::KvStoreNbDelegate *delegate) {
464 ZLOGI("temporary open db for equal identifier, ret:%{public}d", status);
465 if (delegate != nullptr) {
466 KvStoreTuple tuple = { storeMeta.user, storeMeta.appId, storeMeta.storeId };
467 UpgradeManager::SetCompatibleIdentifyByType(delegate, tuple, IDENTICAL_ACCOUNT_GROUP);
468 UpgradeManager::SetCompatibleIdentifyByType(delegate, tuple, PEER_TO_PEER_GROUP);
469 store = delegate;
470 }
471 });
472 ExecutorPool::Task delayTask([store]() {
473 ZLOGI("AutoLaunch:close store after 60s while autolaunch finishied");
474 DistributedDB::KvStoreDelegateManager delegateManager("", "");
475 delegateManager.CloseKvStore(store);
476 });
477 constexpr int CLOSE_STORE_DELAY_TIME = 60; // unit: seconds
478 executors_->Schedule(std::chrono::seconds(CLOSE_STORE_DELAY_TIME), std::move(delayTask));
479 }
480
InitNbDbOption(const Options & options,const std::vector<uint8_t> & cipherKey,DistributedDB::KvStoreNbDelegate::Option & dbOption)481 Status KvStoreDataService::InitNbDbOption(const Options &options, const std::vector<uint8_t> &cipherKey,
482 DistributedDB::KvStoreNbDelegate::Option &dbOption)
483 {
484 DistributedDB::CipherPassword password;
485 auto status = password.SetValue(cipherKey.data(), cipherKey.size());
486 if (status != DistributedDB::CipherPassword::ErrorCode::OK) {
487 ZLOGE("Failed to set the passwd.");
488 return Status::DB_ERROR;
489 }
490
491 dbOption.syncDualTupleMode = true; // tuple of (appid+storeid)
492 dbOption.createIfNecessary = options.createIfMissing;
493 dbOption.isMemoryDb = (!options.persistent);
494 dbOption.isEncryptedDb = options.encrypt;
495 if (options.encrypt) {
496 dbOption.cipher = DistributedDB::CipherType::AES_256_GCM;
497 dbOption.passwd = password;
498 }
499
500 if (options.kvStoreType == KvStoreType::SINGLE_VERSION) {
501 dbOption.conflictResolvePolicy = DistributedDB::LAST_WIN;
502 } else if (options.kvStoreType == KvStoreType::DEVICE_COLLABORATION) {
503 dbOption.conflictResolvePolicy = DistributedDB::DEVICE_COLLABORATION;
504 } else {
505 ZLOGE("kvStoreType is invalid");
506 return Status::INVALID_ARGUMENT;
507 }
508
509 dbOption.schema = options.schema;
510 dbOption.createDirByStoreIdOnly = true;
511 dbOption.secOption = ConvertSecurity(options.securityLevel);
512 return Status::SUCCESS;
513 }
514
OnStop()515 void KvStoreDataService::OnStop()
516 {
517 ZLOGI("begin.");
518 }
519
KvStoreClientDeathObserverImpl(const AppId & appId,KvStoreDataService & service,sptr<IRemoteObject> observer)520 KvStoreDataService::KvStoreClientDeathObserverImpl::KvStoreClientDeathObserverImpl(
521 const AppId &appId, KvStoreDataService &service, sptr<IRemoteObject> observer)
522 : appId_(appId), dataService_(service), observerProxy_(std::move(observer)),
523 deathRecipient_(new KvStoreDeathRecipient(*this))
524 {
525 ZLOGI("KvStoreClientDeathObserverImpl");
526 uid_ = IPCSkeleton::GetCallingUid();
527 pid_ = IPCSkeleton::GetCallingPid();
528 token_ = IPCSkeleton::GetCallingTokenID();
529 if (observerProxy_ != nullptr) {
530 ZLOGI("add death recipient");
531 observerProxy_->AddDeathRecipient(deathRecipient_);
532 } else {
533 ZLOGW("observerProxy_ is nullptr");
534 }
535 }
536
~KvStoreClientDeathObserverImpl()537 KvStoreDataService::KvStoreClientDeathObserverImpl::~KvStoreClientDeathObserverImpl()
538 {
539 ZLOGI("~KvStoreClientDeathObserverImpl");
540 if (deathRecipient_ != nullptr && observerProxy_ != nullptr) {
541 ZLOGI("remove death recipient");
542 observerProxy_->RemoveDeathRecipient(deathRecipient_);
543 }
544 dataService_.features_.ForEachCopies([this](const auto &, sptr<DistributedData::FeatureStubImpl> &value) {
545 value->OnAppExit(uid_, pid_, token_, appId_);
546 return false;
547 });
548 }
549
NotifyClientDie()550 void KvStoreDataService::KvStoreClientDeathObserverImpl::NotifyClientDie()
551 {
552 ZLOGI("appId: %{public}s uid:%{public}d tokenId:%{public}u", appId_.appId.c_str(), uid_, token_);
553 dataService_.AppExit(uid_, pid_, token_, appId_);
554 }
555
GetPid() const556 pid_t KvStoreDataService::KvStoreClientDeathObserverImpl::GetPid() const
557 {
558 return pid_;
559 }
560
KvStoreDeathRecipient(KvStoreClientDeathObserverImpl & kvStoreClientDeathObserverImpl)561 KvStoreDataService::KvStoreClientDeathObserverImpl::KvStoreDeathRecipient::KvStoreDeathRecipient(
562 KvStoreClientDeathObserverImpl &kvStoreClientDeathObserverImpl)
563 : kvStoreClientDeathObserverImpl_(kvStoreClientDeathObserverImpl)
564 {
565 ZLOGI("KvStore Client Death Observer");
566 }
567
~KvStoreDeathRecipient()568 KvStoreDataService::KvStoreClientDeathObserverImpl::KvStoreDeathRecipient::~KvStoreDeathRecipient()
569 {
570 ZLOGI("KvStore Client Death Observer");
571 }
572
OnRemoteDied(const wptr<IRemoteObject> & remote)573 void KvStoreDataService::KvStoreClientDeathObserverImpl::KvStoreDeathRecipient::OnRemoteDied(
574 const wptr<IRemoteObject> &remote)
575 {
576 (void) remote;
577 ZLOGI("begin");
578 kvStoreClientDeathObserverImpl_.NotifyClientDie();
579 }
580
AccountEventChanged(const AccountEventInfo & eventInfo)581 void KvStoreDataService::AccountEventChanged(const AccountEventInfo &eventInfo)
582 {
583 ZLOGI("account event %{public}d changed process, begin.", eventInfo.status);
584 NotifyAccountEvent(eventInfo);
585 switch (eventInfo.status) {
586 case AccountStatus::DEVICE_ACCOUNT_DELETE: {
587 g_kvStoreAccountEventStatus = 1;
588 // delete all kvstore meta belong to this user
589 std::vector<StoreMetaData> metaData;
590 MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({""}), metaData);
591 for (const auto &meta : metaData) {
592 if (meta.user != eventInfo.userId) {
593 continue;
594 }
595 ZLOGI("bundlname:%s, user:%s", meta.bundleName.c_str(), meta.user.c_str());
596 MetaDataManager::GetInstance().DelMeta(meta.GetKey());
597 MetaDataManager::GetInstance().DelMeta(meta.GetStrategyKey());
598 MetaDataManager::GetInstance().DelMeta(meta.GetSecretKey(), true);
599 MetaDataManager::GetInstance().DelMeta(meta.appId, true);
600 MetaDataManager::GetInstance().DelMeta(meta.GetKeyLocal(), true);
601 PermitDelegate::GetInstance().DelCache(meta.GetKey());
602 }
603 g_kvStoreAccountEventStatus = 0;
604 break;
605 }
606 case AccountStatus::DEVICE_ACCOUNT_SWITCHED: {
607 auto ret = DistributedDB::KvStoreDelegateManager::NotifyUserChanged();
608 ZLOGI("notify delegate manager result:%{public}d", ret);
609 break;
610 }
611 default: {
612 break;
613 }
614 }
615 ZLOGI("account event %{public}d changed process, end.", eventInfo.status);
616 }
617
NotifyAccountEvent(const AccountEventInfo & eventInfo)618 void KvStoreDataService::NotifyAccountEvent(const AccountEventInfo &eventInfo)
619 {
620 features_.ForEachCopies([&eventInfo](const auto &key, sptr<DistributedData::FeatureStubImpl> &value) {
621 value->OnUserChange(uint32_t(eventInfo.status), eventInfo.userId, eventInfo.harmonyAccountId);
622 return false;
623 });
624
625 if (eventInfo.status == AccountStatus::DEVICE_ACCOUNT_SWITCHED) {
626 features_.Erase("data_share");
627 }
628 }
629
InitSecurityAdapter(std::shared_ptr<ExecutorPool> executors)630 void KvStoreDataService::InitSecurityAdapter(std::shared_ptr<ExecutorPool> executors)
631 {
632 auto ret = DATASL_OnStart();
633 ZLOGI("datasl on start ret:%d", ret);
634 security_ = std::make_shared<Security>(executors);
635 if (security_ == nullptr) {
636 ZLOGE("security is nullptr.");
637 return;
638 }
639
640 auto dbStatus = DistributedDB::RuntimeConfig::SetProcessSystemAPIAdapter(security_);
641 ZLOGD("set distributed db system api adapter: %d.", static_cast<int>(dbStatus));
642
643 auto status = DmAdapter::GetInstance().StartWatchDeviceChange(security_.get(), {"security"});
644 if (status != Status::SUCCESS) {
645 ZLOGD("security register device change failed, status:%d", static_cast<int>(status));
646 }
647 }
648
SetCompatibleIdentify(const AppDistributedKv::DeviceInfo & info) const649 void KvStoreDataService::SetCompatibleIdentify(const AppDistributedKv::DeviceInfo &info) const
650 {
651 }
652
OnDeviceOnline(const AppDistributedKv::DeviceInfo & info)653 void KvStoreDataService::OnDeviceOnline(const AppDistributedKv::DeviceInfo &info)
654 {
655 if (info.uuid.empty()) {
656 return;
657 }
658 features_.ForEachCopies([&info](const auto &key, sptr<DistributedData::FeatureStubImpl> &value) {
659 value->Online(info.uuid);
660 return false;
661 });
662 }
663
OnDeviceOffline(const AppDistributedKv::DeviceInfo & info)664 void KvStoreDataService::OnDeviceOffline(const AppDistributedKv::DeviceInfo &info)
665 {
666 if (info.uuid.empty()) {
667 return;
668 }
669 features_.ForEachCopies([&info](const auto &key, sptr<DistributedData::FeatureStubImpl> &value) {
670 value->Offline(info.uuid);
671 return false;
672 });
673 }
674
OnDeviceOnReady(const AppDistributedKv::DeviceInfo & info)675 void KvStoreDataService::OnDeviceOnReady(const AppDistributedKv::DeviceInfo &info)
676 {
677 if (info.uuid.empty()) {
678 return;
679 }
680 features_.ForEachCopies([&info](const auto &key, sptr<DistributedData::FeatureStubImpl> &value) {
681 value->OnReady(info.uuid);
682 return false;
683 });
684 }
685
OnUninstall(const std::string & bundleName,int32_t user,int32_t index)686 int32_t KvStoreDataService::OnUninstall(const std::string &bundleName, int32_t user, int32_t index)
687 {
688 features_.ForEachCopies(
689 [bundleName, user, index](const auto &, sptr<DistributedData::FeatureStubImpl> &value) {
690 value->OnAppUninstall(bundleName, user, index);
691 return false;
692 });
693 return 0;
694 }
695
OnUpdate(const std::string & bundleName,int32_t user,int32_t index)696 int32_t KvStoreDataService::OnUpdate(const std::string &bundleName, int32_t user, int32_t index)
697 {
698 features_.ForEachCopies(
699 [bundleName, user, index](const auto &, sptr<DistributedData::FeatureStubImpl> &value) {
700 value->OnAppUpdate(bundleName, user, index);
701 return false;
702 });
703 return 0;
704 }
705 } // namespace OHOS::DistributedKv
706