• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #define LOG_TAG "KvStoreDataService"
16 #include "kvstore_data_service.h"
17 
18 #include <chrono>
19 #include <ipc_skeleton.h>
20 #include <thread>
21 
22 #include "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 &param) -> bool {
325         auto status = ResolveAutoLaunchParamByIdentifier(identifier, param);
326         features_.ForEachCopies([&identifier, &param](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 &param)
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