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