1 /*
2  * Copyright (c) 2022-2024 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 "KVDBServiceImpl"
16 #include "kvdb_service_impl.h"
17 
18 #include <chrono>
19 #include <cinttypes>
20 
21 #include "accesstoken_kit.h"
22 #include "account/account_delegate.h"
23 #include "backup_manager.h"
24 #include "bootstrap.h"
25 #include "checker/checker_manager.h"
26 #include "cloud/change_event.h"
27 #include "cloud/cloud_server.h"
28 #include "communication_provider.h"
29 #include "communicator_context.h"
30 #include "crypto_manager.h"
31 #include "device_manager_adapter.h"
32 #include "directory/directory_manager.h"
33 #include "dump/dump_manager.h"
34 #include "eventcenter/event_center.h"
35 #include "ipc_skeleton.h"
36 #include "kvdb_general_store.h"
37 #include "kvdb_query.h"
38 #include "kv_radar_reporter.h"
39 #include "log_print.h"
40 #include "matrix_event.h"
41 #include "metadata/appid_meta_data.h"
42 #include "metadata/capability_meta_data.h"
43 #include "metadata/switches_meta_data.h"
44 #include "permit_delegate.h"
45 #include "query_helper.h"
46 #include "store/store_info.h"
47 #include "upgrade.h"
48 #include "utils/anonymous.h"
49 #include "utils/constant.h"
50 #include "utils/converter.h"
51 #include "water_version_manager.h"
52 #include "app_id_mapping/app_id_mapping_config_manager.h"
53 
54 namespace OHOS::DistributedKv {
55 using namespace OHOS::DistributedData;
56 using namespace OHOS::AppDistributedKv;
57 using namespace OHOS::Security::AccessToken;
58 using system_clock = std::chrono::system_clock;
59 using DMAdapter = DistributedData::DeviceManagerAdapter;
60 using DumpManager = OHOS::DistributedData::DumpManager;
61 using CommContext = OHOS::DistributedData::CommunicatorContext;
62 using SecretKeyMeta = DistributedData::SecretKeyMetaData;
63 static constexpr const char *DEFAULT_USER_ID = "0";
64 static constexpr const char *PASTEBOARD_SERVICE = "pasteboard_service";
65 static constexpr const char *PASTEBOARD_USER_ID = "100";
66 __attribute__((used)) KVDBServiceImpl::Factory KVDBServiceImpl::factory_;
Factory()67 KVDBServiceImpl::Factory::Factory()
68 {
69     FeatureSystem::GetInstance().RegisterCreator("kv_store", [this]() {
70         if (product_ == nullptr) {
71             product_ = std::make_shared<KVDBServiceImpl>();
72         }
73         return product_;
74     });
75     auto creator = [](const StoreMetaData &metaData) -> GeneralStore* {
76         auto store = new (std::nothrow) KVDBGeneralStore(metaData);
77         if (store != nullptr && !store->IsValid()) {
78             delete store;
79             store = nullptr;
80         }
81         return store;
82     };
83     AutoCache::GetInstance().RegCreator(KvStoreType::SINGLE_VERSION, creator);
84     AutoCache::GetInstance().RegCreator(KvStoreType::DEVICE_COLLABORATION, creator);
85 }
86 
~Factory()87 KVDBServiceImpl::Factory::~Factory()
88 {
89     product_ = nullptr;
90 }
91 
KVDBServiceImpl()92 KVDBServiceImpl::KVDBServiceImpl()
93 {
94 }
95 
~KVDBServiceImpl()96 KVDBServiceImpl::~KVDBServiceImpl()
97 {
98     DumpManager::GetInstance().RemoveHandler("FEATURE_INFO", uintptr_t(this));
99 }
100 
Init()101 void KVDBServiceImpl::Init()
102 {
103     auto process = [this](const Event &event) {
104         const auto &evt = static_cast<const CloudEvent &>(event);
105         const auto &storeInfo = evt.GetStoreInfo();
106         StoreMetaData meta(storeInfo);
107         meta.deviceId = DMAdapter::GetInstance().GetLocalDevice().uuid;
108         if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true)) {
109             ZLOGE("meta empty, bundleName:%{public}s, storeId:%{public}s, user = %{public}s", meta.bundleName.c_str(),
110                 meta.GetStoreAlias().c_str(), meta.user.c_str());
111             if (meta.user == "0") {
112                 return;
113             }
114             meta.user = "0";
115             StoreMetaDataLocal localMeta;
116             if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKeyLocal(), localMeta, true) || !localMeta.isPublic ||
117                 !MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true)) {
118                 ZLOGE("meta empty, not public store.");
119                 return;
120             }
121         }
122         if (meta.storeType < StoreMetaData::StoreType::STORE_KV_BEGIN ||
123             meta.storeType > StoreMetaData::StoreType::STORE_KV_END) {
124             return;
125         }
126         auto watchers = GetWatchers(meta.tokenId, meta.storeId);
127         auto store = AutoCache::GetInstance().GetStore(meta, watchers);
128         if (store == nullptr) {
129             ZLOGE("store null, storeId:%{public}s", meta.GetStoreAlias().c_str());
130             return;
131         }
132         store->RegisterDetailProgressObserver(nullptr);
133     };
134     EventCenter::GetInstance().Subscribe(CloudEvent::CLOUD_SYNC, process);
135     EventCenter::GetInstance().Subscribe(CloudEvent::CLEAN_DATA, process);
136 }
137 
RegisterKvServiceInfo()138 void KVDBServiceImpl::RegisterKvServiceInfo()
139 {
140     OHOS::DistributedData::DumpManager::Config serviceInfoConfig;
141     serviceInfoConfig.fullCmd = "--feature-info";
142     serviceInfoConfig.abbrCmd = "-f";
143     serviceInfoConfig.dumpName = "FEATURE_INFO";
144     serviceInfoConfig.dumpCaption = { "| Display all the service statistics" };
145     DumpManager::GetInstance().AddConfig("FEATURE_INFO", serviceInfoConfig);
146 }
147 
RegisterHandler()148 void KVDBServiceImpl::RegisterHandler()
149 {
150     Handler handler =
151         std::bind(&KVDBServiceImpl::DumpKvServiceInfo, this, std::placeholders::_1, std::placeholders::_2);
152     DumpManager::GetInstance().AddHandler("FEATURE_INFO", uintptr_t(this), handler);
153 }
154 
DumpKvServiceInfo(int fd,std::map<std::string,std::vector<std::string>> & params)155 void KVDBServiceImpl::DumpKvServiceInfo(int fd, std::map<std::string, std::vector<std::string>> &params)
156 {
157     (void)params;
158     std::string info;
159     dprintf(fd, "-------------------------------------KVDBServiceInfo------------------------------\n%s\n",
160         info.c_str());
161 }
162 
GetStoreIds(const AppId & appId,std::vector<StoreId> & storeIds)163 Status KVDBServiceImpl::GetStoreIds(const AppId &appId, std::vector<StoreId> &storeIds)
164 {
165     std::vector<StoreMetaData> metaData;
166     auto user = AccountDelegate::GetInstance()->GetUserByToken(IPCSkeleton::GetCallingTokenID());
167     auto deviceId = DMAdapter::GetInstance().GetLocalDevice().uuid;
168     auto prefix = StoreMetaData::GetPrefix({ deviceId, std::to_string(user), "default", appId.appId });
169     auto instanceId = GetInstIndex(IPCSkeleton::GetCallingTokenID(), appId);
170     MetaDataManager::GetInstance().LoadMeta(prefix, metaData, true);
171     for (auto &item : metaData) {
172         if (item.storeType > KvStoreType::MULTI_VERSION || item.instanceId != instanceId) {
173             continue;
174         }
175         storeIds.push_back({ item.storeId });
176     }
177     ZLOGD("appId:%{public}s store size:%{public}zu", appId.appId.c_str(), storeIds.size());
178     return SUCCESS;
179 }
180 
Delete(const AppId & appId,const StoreId & storeId)181 Status KVDBServiceImpl::Delete(const AppId &appId, const StoreId &storeId)
182 {
183     StoreMetaData metaData = GetStoreMetaData(appId, storeId);
184     if (metaData.instanceId < 0) {
185         return ILLEGAL_STATE;
186     }
187 
188     auto tokenId = IPCSkeleton::GetCallingTokenID();
189     syncAgents_.ComputeIfPresent(tokenId, [&appId, &storeId](auto &key, SyncAgent &syncAgent) {
190         if (syncAgent.pid_ != IPCSkeleton::GetCallingPid()) {
191             ZLOGW("agent already changed! old pid:%{public}d new pid:%{public}d appId:%{public}s",
192                 IPCSkeleton::GetCallingPid(), syncAgent.pid_, appId.appId.c_str());
193             return true;
194         }
195         syncAgent.delayTimes_.erase(storeId);
196         return true;
197     });
198     MetaDataManager::GetInstance().DelMeta(metaData.GetKey());
199     MetaDataManager::GetInstance().DelMeta(metaData.GetKey(), true);
200     MetaDataManager::GetInstance().DelMeta(metaData.GetKeyLocal(), true);
201     MetaDataManager::GetInstance().DelMeta(metaData.GetSecretKey(), true);
202     MetaDataManager::GetInstance().DelMeta(metaData.GetStrategyKey());
203     MetaDataManager::GetInstance().DelMeta(metaData.GetBackupSecretKey(), true);
204     MetaDataManager::GetInstance().DelMeta(metaData.GetAutoLaunchKey(), true);
205     MetaDataManager::GetInstance().DelMeta(metaData.GetDebugInfoKey(), true);
206     PermitDelegate::GetInstance().DelCache(metaData.GetKey());
207     AutoCache::GetInstance().CloseStore(tokenId, storeId);
208     ZLOGD("appId:%{public}s storeId:%{public}s instanceId:%{public}d", appId.appId.c_str(),
209         Anonymous::Change(storeId.storeId).c_str(), metaData.instanceId);
210     return SUCCESS;
211 }
212 
Close(const AppId & appId,const StoreId & storeId)213 Status KVDBServiceImpl::Close(const AppId &appId, const StoreId &storeId)
214 {
215     StoreMetaData metaData = GetStoreMetaData(appId, storeId);
216     if (metaData.instanceId < 0) {
217         return ILLEGAL_STATE;
218     }
219     auto tokenId = IPCSkeleton::GetCallingTokenID();
220     AutoCache::GetInstance().CloseStore(tokenId, storeId);
221     ZLOGD("appId:%{public}s storeId:%{public}s instanceId:%{public}d", appId.appId.c_str(),
222         Anonymous::Change(storeId.storeId).c_str(), metaData.instanceId);
223     return SUCCESS;
224 }
225 
CloudSync(const AppId & appId,const StoreId & storeId,const SyncInfo & syncInfo)226 Status KVDBServiceImpl::CloudSync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo)
227 {
228     StoreMetaData metaData = GetStoreMetaData(appId, storeId);
229     if (!MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData, true)) {
230         ZLOGE("invalid, appId:%{public}s storeId:%{public}s",
231             appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str());
232         return Status::INVALID_ARGUMENT;
233     }
234     return DoCloudSync(metaData, syncInfo);
235 }
236 
OnAsyncComplete(uint32_t tokenId,uint64_t seqNum,ProgressDetail && detail)237 void KVDBServiceImpl::OnAsyncComplete(uint32_t tokenId, uint64_t seqNum, ProgressDetail &&detail)
238 {
239     ZLOGI("tokenId=%{public}x seqnum=%{public}" PRIu64, tokenId, seqNum);
240     auto [success, agent] = syncAgents_.Find(tokenId);
241     if (success && agent.notifier_ != nullptr) {
242         agent.notifier_->SyncCompleted(seqNum, std::move(detail));
243     }
244 }
245 
Sync(const AppId & appId,const StoreId & storeId,SyncInfo & syncInfo)246 Status KVDBServiceImpl::Sync(const AppId &appId, const StoreId &storeId, SyncInfo &syncInfo)
247 {
248     StoreMetaData metaData = GetStoreMetaData(appId, storeId);
249     MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData);
250     auto delay = GetSyncDelayTime(syncInfo.delay, storeId);
251     if (metaData.isAutoSync && syncInfo.seqId == std::numeric_limits<uint64_t>::max()) {
252         DeviceMatrix::GetInstance().OnChanged(metaData);
253         StoreMetaDataLocal localMeta;
254         MetaDataManager::GetInstance().LoadMeta(metaData.GetKeyLocal(), localMeta, true);
255         if (!localMeta.HasPolicy(IMMEDIATE_SYNC_ON_CHANGE)) {
256             ZLOGW("appId:%{public}s storeId:%{public}s no IMMEDIATE_SYNC_ON_CHANGE ", appId.appId.c_str(),
257                 Anonymous::Change(storeId.storeId).c_str());
258             return Status::SUCCESS;
259         }
260     }
261     syncInfo.syncId = ++syncId_;
262     RADAR_REPORT(STANDARD_DEVICE_SYNC, ADD_SYNC_TASK, RADAR_SUCCESS, BIZ_STATE, START,
263         SYNC_STORE_ID, Anonymous::Change(storeId.storeId), SYNC_APP_ID, appId.appId, CONCURRENT_ID,
264         std::to_string(syncInfo.syncId), DATA_TYPE, metaData.dataType, SYNC_TYPE,
265         SYNC, OS_TYPE, IsOHOSType(syncInfo.devices));
266     return KvStoreSyncManager::GetInstance()->AddSyncOperation(uintptr_t(metaData.tokenId), delay,
267         std::bind(&KVDBServiceImpl::DoSyncInOrder, this, metaData, syncInfo, std::placeholders::_1, ACTION_SYNC),
268         std::bind(&KVDBServiceImpl::DoComplete, this, metaData, syncInfo, RefCount(), std::placeholders::_1));
269 }
270 
NotifyDataChange(const AppId & appId,const StoreId & storeId,uint64_t delay)271 Status KVDBServiceImpl::NotifyDataChange(const AppId &appId, const StoreId &storeId, uint64_t delay)
272 {
273     StoreMetaData meta = GetStoreMetaData(appId, storeId);
274     if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta)) {
275         ZLOGE("invalid, appId:%{public}s storeId:%{public}s",
276             appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str());
277         return Status::INVALID_ARGUMENT;
278     }
279     if (DeviceMatrix::GetInstance().IsSupportMatrix() &&
280         (DeviceMatrix::GetInstance().IsStatics(meta) || DeviceMatrix::GetInstance().IsDynamic(meta))) {
281         WaterVersionManager::GetInstance().GenerateWaterVersion(meta.bundleName, meta.storeId);
282         DeviceMatrix::GetInstance().OnChanged(meta);
283     }
284 
285     if (executors_ != nullptr && (meta.cloudAutoSync)) {
286         executors_->Schedule(std::chrono::milliseconds(delay), [this, meta]() {
287             if (meta.cloudAutoSync) {
288                 DoCloudSync(meta, {});
289             }
290         });
291     }
292     return SUCCESS;
293 }
294 
PutSwitch(const AppId & appId,const SwitchData & data)295 Status KVDBServiceImpl::PutSwitch(const AppId &appId, const SwitchData &data)
296 {
297     if (data.value == DeviceMatrix::INVALID_VALUE || data.length == DeviceMatrix::INVALID_LENGTH) {
298         return Status::INVALID_ARGUMENT;
299     }
300     auto deviceId = DMAdapter::GetInstance().GetLocalDevice().uuid;
301     SwitchesMetaData oldMeta;
302     oldMeta.deviceId = deviceId;
303     bool exist = MetaDataManager::GetInstance().LoadMeta(oldMeta.GetKey(), oldMeta, true);
304     SwitchesMetaData newMeta;
305     newMeta.value = data.value;
306     newMeta.length = data.length;
307     newMeta.deviceId = deviceId;
308     if (!exist || newMeta != oldMeta) {
309         bool success = MetaDataManager::GetInstance().SaveMeta(newMeta.GetKey(), newMeta, true);
310         if (success) {
311             ZLOGI("start broadcast swicthes data");
312             DeviceMatrix::DataLevel level = {
313                 .switches = data.value,
314                 .switchesLen = data.length,
315             };
316             RADAR_REPORT(BROADCAST_DEVICE_SYNC, SEND_BROADCAST, RADAR_START, BIZ_STATE, START,
317                 SYNC_APP_ID, appId.appId);
318             DeviceMatrix::GetInstance().Broadcast(level);
319             RADAR_REPORT(BROADCAST_DEVICE_SYNC, SEND_BROADCAST, RADAR_SUCCESS, BIZ_STATE, END,
320                 SYNC_APP_ID, appId.appId);
321         }
322     }
323     ZLOGI("appId:%{public}s, exist:%{public}d, saved:%{public}d", appId.appId.c_str(), exist, newMeta != oldMeta);
324     return Status::SUCCESS;
325 }
326 
GetSwitch(const AppId & appId,const std::string & networkId,SwitchData & data)327 Status KVDBServiceImpl::GetSwitch(const AppId &appId, const std::string &networkId, SwitchData &data)
328 {
329     auto uuid = DMAdapter::GetInstance().ToUUID(networkId);
330     if (uuid.empty()) {
331         return Status::INVALID_ARGUMENT;
332     }
333     SwitchesMetaData meta;
334     meta.deviceId = uuid;
335     if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true)) {
336         return Status::NOT_FOUND;
337     }
338     data.value = meta.value;
339     data.length = meta.length;
340     return Status::SUCCESS;
341 }
342 
RegServiceNotifier(const AppId & appId,sptr<IKVDBNotifier> notifier)343 Status KVDBServiceImpl::RegServiceNotifier(const AppId &appId, sptr<IKVDBNotifier> notifier)
344 {
345     auto tokenId = IPCSkeleton::GetCallingTokenID();
346     syncAgents_.Compute(tokenId, [&appId, notifier](const auto &, SyncAgent &value) {
347         if (value.pid_ != IPCSkeleton::GetCallingPid()) {
348             value.ReInit(IPCSkeleton::GetCallingPid(), appId);
349         }
350         value.notifier_ = notifier;
351         return true;
352     });
353     return Status::SUCCESS;
354 }
355 
UnregServiceNotifier(const AppId & appId)356 Status KVDBServiceImpl::UnregServiceNotifier(const AppId &appId)
357 {
358     syncAgents_.ComputeIfPresent(IPCSkeleton::GetCallingTokenID(), [&appId](const auto &key, SyncAgent &value) {
359         if (value.pid_ != IPCSkeleton::GetCallingPid()) {
360             ZLOGW("agent already changed! old pid:%{public}d, new pid:%{public}d, appId:%{public}s",
361                 IPCSkeleton::GetCallingPid(), value.pid_, appId.appId.c_str());
362             return true;
363         }
364         value.notifier_ = nullptr;
365         return true;
366     });
367     return SUCCESS;
368 }
369 
SubscribeSwitchData(const AppId & appId)370 Status KVDBServiceImpl::SubscribeSwitchData(const AppId &appId)
371 {
372     sptr<IKVDBNotifier> notifier = nullptr;
373     auto tokenId = IPCSkeleton::GetCallingTokenID();
374     syncAgents_.Compute(tokenId, [&appId, &notifier](const auto &, SyncAgent &value) {
375         if (value.pid_ != IPCSkeleton::GetCallingPid()) {
376             value.ReInit(IPCSkeleton::GetCallingPid(), appId);
377         }
378         if (value.switchesObserverCount_ == 0) {
379             notifier = value.notifier_;
380         }
381         value.switchesObserverCount_++;
382         return true;
383     });
384     if (notifier == nullptr) {
385         return SUCCESS;
386     }
387     bool success = MetaDataManager::GetInstance().Subscribe(SwitchesMetaData::GetPrefix({}),
388         [this, notifier](const std::string &key, const std::string &meta, int32_t action) {
389             SwitchesMetaData metaData;
390             if (!SwitchesMetaData::Unmarshall(meta, metaData)) {
391                 ZLOGE("unmarshall matrix meta failed, action:%{public}d", action);
392                 return true;
393             }
394             auto networkId = DMAdapter::GetInstance().ToNetworkID(metaData.deviceId);
395             SwitchNotification notification;
396             notification.deviceId = std::move(networkId);
397             notification.data.value = metaData.value;
398             notification.data.length = metaData.length;
399             notification.state = ConvertAction(static_cast<Action>(action));
400             if (notifier != nullptr) {
401                 notifier->OnSwitchChange(std::move(notification));
402             }
403             return true;
404         }, true);
405     ZLOGI("subscribe switch status:%{public}d", success);
406     return SUCCESS;
407 }
408 
UnsubscribeSwitchData(const AppId & appId)409 Status KVDBServiceImpl::UnsubscribeSwitchData(const AppId &appId)
410 {
411     bool destroyed = false;
412     auto tokenId = IPCSkeleton::GetCallingTokenID();
413     syncAgents_.ComputeIfPresent(tokenId, [&destroyed](auto &key, SyncAgent &value) {
414         if (value.switchesObserverCount_ > 0) {
415             value.switchesObserverCount_--;
416         }
417         if (value.switchesObserverCount_ == 0) {
418             destroyed = true;
419         }
420         return true;
421     });
422     if (destroyed) {
423         bool status = MetaDataManager::GetInstance().Unsubscribe(SwitchesMetaData::GetPrefix({}));
424         ZLOGI("unsubscribe switch status %{public}d", status);
425     }
426     return SUCCESS;
427 }
428 
HandleGenDetails(const GenDetails & details)429 ProgressDetail KVDBServiceImpl::HandleGenDetails(const GenDetails &details)
430 {
431     ProgressDetail progressDetail;
432     if (details.begin() == details.end()) {
433         return {};
434     }
435     auto genDetail = details.begin()->second;
436     progressDetail.progress = genDetail.progress;
437     progressDetail.code = genDetail.code;
438     auto tableDetails = genDetail.details;
439     if (tableDetails.begin() == tableDetails.end()) {
440         return progressDetail;
441     }
442     auto genTableDetail = tableDetails.begin()->second;
443     auto &tableDetail = progressDetail.details;
444     Constant::Copy(&tableDetail, &genTableDetail);
445     return progressDetail;
446 }
447 
SetSyncParam(const AppId & appId,const StoreId & storeId,const KvSyncParam & syncParam)448 Status KVDBServiceImpl::SetSyncParam(const AppId &appId, const StoreId &storeId, const KvSyncParam &syncParam)
449 {
450     if (syncParam.allowedDelayMs > 0 && syncParam.allowedDelayMs < KvStoreSyncManager::SYNC_MIN_DELAY_MS) {
451         return Status::INVALID_ARGUMENT;
452     }
453     if (syncParam.allowedDelayMs > KvStoreSyncManager::SYNC_MAX_DELAY_MS) {
454         return Status::INVALID_ARGUMENT;
455     }
456     auto tokenId = IPCSkeleton::GetCallingTokenID();
457     syncAgents_.Compute(tokenId, [&appId, &storeId, &syncParam](auto &key, SyncAgent &value) {
458         if (value.pid_ != IPCSkeleton::GetCallingPid()) {
459             value.ReInit(IPCSkeleton::GetCallingPid(), appId);
460         }
461         value.delayTimes_[storeId] = syncParam.allowedDelayMs;
462         return true;
463     });
464     return SUCCESS;
465 }
466 
GetSyncParam(const AppId & appId,const StoreId & storeId,KvSyncParam & syncParam)467 Status KVDBServiceImpl::GetSyncParam(const AppId &appId, const StoreId &storeId, KvSyncParam &syncParam)
468 {
469     syncParam.allowedDelayMs = 0;
470     auto tokenId = IPCSkeleton::GetCallingTokenID();
471     syncAgents_.ComputeIfPresent(tokenId, [&appId, &storeId, &syncParam](auto &key, SyncAgent &value) {
472         if (value.pid_ != IPCSkeleton::GetCallingPid()) {
473             ZLOGW("agent already changed! old pid:%{public}d, new pid:%{public}d, appId:%{public}s",
474                 IPCSkeleton::GetCallingPid(), value.pid_, appId.appId.c_str());
475             return true;
476         }
477 
478         auto it = value.delayTimes_.find(storeId);
479         if (it != value.delayTimes_.end()) {
480             syncParam.allowedDelayMs = it->second;
481         }
482         return true;
483     });
484     return SUCCESS;
485 }
486 
EnableCapability(const AppId & appId,const StoreId & storeId)487 Status KVDBServiceImpl::EnableCapability(const AppId &appId, const StoreId &storeId)
488 {
489     StrategyMeta strategyMeta = GetStrategyMeta(appId, storeId);
490     if (strategyMeta.instanceId < 0) {
491         return ILLEGAL_STATE;
492     }
493     MetaDataManager::GetInstance().LoadMeta(strategyMeta.GetKey(), strategyMeta);
494     strategyMeta.capabilityEnabled = true;
495     MetaDataManager::GetInstance().SaveMeta(strategyMeta.GetKey(), strategyMeta);
496     return SUCCESS;
497 }
498 
DisableCapability(const AppId & appId,const StoreId & storeId)499 Status KVDBServiceImpl::DisableCapability(const AppId &appId, const StoreId &storeId)
500 {
501     StrategyMeta strategyMeta = GetStrategyMeta(appId, storeId);
502     if (strategyMeta.instanceId < 0) {
503         return ILLEGAL_STATE;
504     }
505     MetaDataManager::GetInstance().LoadMeta(strategyMeta.GetKey(), strategyMeta);
506     strategyMeta.capabilityEnabled = false;
507     MetaDataManager::GetInstance().SaveMeta(strategyMeta.GetKey(), strategyMeta);
508     return SUCCESS;
509 }
510 
SetCapability(const AppId & appId,const StoreId & storeId,const std::vector<std::string> & local,const std::vector<std::string> & remote)511 Status KVDBServiceImpl::SetCapability(const AppId &appId, const StoreId &storeId,
512     const std::vector<std::string> &local, const std::vector<std::string> &remote)
513 {
514     StrategyMeta strategy = GetStrategyMeta(appId, storeId);
515     if (strategy.instanceId < 0) {
516         return ILLEGAL_STATE;
517     }
518     MetaDataManager::GetInstance().LoadMeta(strategy.GetKey(), strategy);
519     strategy.capabilityRange.localLabel = local;
520     strategy.capabilityRange.remoteLabel = remote;
521     MetaDataManager::GetInstance().SaveMeta(strategy.GetKey(), strategy);
522     return SUCCESS;
523 }
524 
AddSubscribeInfo(const AppId & appId,const StoreId & storeId,const SyncInfo & syncInfo)525 Status KVDBServiceImpl::AddSubscribeInfo(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo)
526 {
527     StoreMetaData metaData = GetStoreMetaData(appId, storeId);
528     MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData);
529     auto delay = GetSyncDelayTime(syncInfo.delay, storeId);
530     return KvStoreSyncManager::GetInstance()->AddSyncOperation(uintptr_t(metaData.tokenId), delay,
531         std::bind(&KVDBServiceImpl::DoSyncInOrder, this, metaData, syncInfo, std::placeholders::_1, ACTION_SUBSCRIBE),
532         std::bind(&KVDBServiceImpl::DoComplete, this, metaData, syncInfo, RefCount(), std::placeholders::_1));
533 }
534 
RmvSubscribeInfo(const AppId & appId,const StoreId & storeId,const SyncInfo & syncInfo)535 Status KVDBServiceImpl::RmvSubscribeInfo(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo)
536 {
537     StoreMetaData metaData = GetStoreMetaData(appId, storeId);
538     MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData);
539     auto delay = GetSyncDelayTime(syncInfo.delay, storeId);
540     return KvStoreSyncManager::GetInstance()->AddSyncOperation(uintptr_t(metaData.tokenId), delay,
541         std::bind(
542             &KVDBServiceImpl::DoSyncInOrder, this, metaData, syncInfo, std::placeholders::_1, ACTION_UNSUBSCRIBE),
543         std::bind(&KVDBServiceImpl::DoComplete, this, metaData, syncInfo, RefCount(), std::placeholders::_1));
544 }
545 
Subscribe(const AppId & appId,const StoreId & storeId,sptr<IKvStoreObserver> observer)546 Status KVDBServiceImpl::Subscribe(const AppId &appId, const StoreId &storeId, sptr<IKvStoreObserver> observer)
547 {
548     if (observer == nullptr) {
549         return INVALID_ARGUMENT;
550     }
551     auto tokenId = IPCSkeleton::GetCallingTokenID();
552     ZLOGI("appId:%{public}s storeId:%{public}s tokenId:0x%{public}x", appId.appId.c_str(),
553         Anonymous::Change(storeId.storeId).c_str(), tokenId);
554     bool isCreate = false;
555     syncAgents_.Compute(tokenId, [&appId, &storeId, &observer, &isCreate](auto &key, SyncAgent &agent) {
556         if (agent.pid_ != IPCSkeleton::GetCallingPid()) {
557             agent.ReInit(IPCSkeleton::GetCallingPid(), appId);
558         }
559         isCreate = true;
560         auto watcher = std::make_shared<KVDBWatcher>();
561         watcher->SetObserver(observer);
562         agent.watchers_[storeId.storeId].insert(watcher);
563         return true;
564     });
565     if (isCreate) {
566         AutoCache::GetInstance().SetObserver(tokenId, storeId, GetWatchers(tokenId, storeId));
567     }
568     return SUCCESS;
569 }
570 
Unsubscribe(const AppId & appId,const StoreId & storeId,sptr<IKvStoreObserver> observer)571 Status KVDBServiceImpl::Unsubscribe(const AppId &appId, const StoreId &storeId, sptr<IKvStoreObserver> observer)
572 {
573     auto tokenId = IPCSkeleton::GetCallingTokenID();
574     ZLOGI("appId:%{public}s storeId:%{public}s tokenId:0x%{public}x", appId.appId.c_str(),
575         Anonymous::Change(storeId.storeId).c_str(), tokenId);
576     bool destroyed = false;
577     syncAgents_.ComputeIfPresent(tokenId, [&appId, &storeId, &observer, &destroyed](auto &key, SyncAgent &agent) {
578         auto iter = agent.watchers_.find(storeId.storeId);
579         if (iter == agent.watchers_.end()) {
580             return true;
581         }
582         for (auto watcher : iter->second) {
583             if (watcher->GetObserver() == observer) {
584                 destroyed = true;
585                 iter->second.erase(watcher);
586                 break;
587             }
588         }
589         if (iter->second.size() == 0) {
590             agent.watchers_.erase(storeId.storeId);
591         }
592         return true;
593     });
594     if (destroyed) {
595         AutoCache::GetInstance().SetObserver(tokenId, storeId, GetWatchers(tokenId, storeId));
596     }
597     return SUCCESS;
598 }
599 
GetBackupPassword(const AppId & appId,const StoreId & storeId,std::vector<uint8_t> & password,int32_t passwordType)600 Status KVDBServiceImpl::GetBackupPassword(const AppId &appId, const StoreId &storeId, std::vector<uint8_t> &password,
601     int32_t passwordType)
602 {
603     StoreMetaData metaData = GetStoreMetaData(appId, storeId);
604     if (passwordType == KVDBService::PasswordType::BACKUP_SECRET_KEY) {
605         return BackupManager::GetInstance().GetPassWord(metaData, password) ? SUCCESS : ERROR;
606     }
607     if (passwordType == KVDBService::PasswordType::SECRET_KEY) {
608         SecretKeyMetaData secretKey;
609         MetaDataManager::GetInstance().LoadMeta(metaData.GetSecretKey(), secretKey, true);
610         return CryptoManager::GetInstance().Decrypt(secretKey.sKey, password) ? SUCCESS : ERROR;
611     }
612     ZLOGE("passwordType is invalid, appId:%{public}s, storeId:%{public}s, passwordType:%{public}d",
613         appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str(), passwordType);
614     return ERROR;
615 }
616 
SetConfig(const AppId & appId,const StoreId & storeId,const StoreConfig & storeConfig)617 Status KVDBServiceImpl::SetConfig(const AppId &appId, const StoreId &storeId, const StoreConfig &storeConfig)
618 {
619     StoreMetaData meta = GetStoreMetaData(appId, storeId);
620     auto isCreated = MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true);
621     if (!isCreated) {
622         return SUCCESS;
623     }
624     meta.enableCloud = storeConfig.cloudConfig.enableCloud;
625     meta.cloudAutoSync = storeConfig.cloudConfig.autoSync;
626     if (!MetaDataManager::GetInstance().SaveMeta(meta.GetKey(), meta, true)) {
627         return Status::ERROR;
628     }
629     StoreMetaData syncMeta;
630     if (MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), syncMeta)) {
631         syncMeta.enableCloud = storeConfig.cloudConfig.enableCloud;
632         syncMeta.cloudAutoSync = storeConfig.cloudConfig.autoSync;
633         if (!MetaDataManager::GetInstance().SaveMeta(syncMeta.GetKey(), syncMeta)) {
634             return Status::ERROR;
635         }
636     }
637     auto stores = AutoCache::GetInstance().GetStoresIfPresent(meta.tokenId, storeId);
638     for (auto store : stores) {
639         store->SetConfig({ storeConfig.cloudConfig.enableCloud });
640     }
641     ZLOGI("appId:%{public}s storeId:%{public}s enable:%{public}d", appId.appId.c_str(),
642         Anonymous::Change(storeId.storeId).c_str(), storeConfig.cloudConfig.enableCloud);
643     return Status::SUCCESS;
644 }
645 
BeforeCreate(const AppId & appId,const StoreId & storeId,const Options & options)646 Status KVDBServiceImpl::BeforeCreate(const AppId &appId, const StoreId &storeId, const Options &options)
647 {
648     ZLOGD("appId:%{public}s storeId:%{public}s to export data", appId.appId.c_str(),
649         Anonymous::Change(storeId.storeId).c_str());
650     StoreMetaData meta = GetStoreMetaData(appId, storeId);
651     AddOptions(options, meta);
652 
653     StoreMetaData old;
654     auto isCreated = MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), old, true);
655     if (!isCreated) {
656         return SUCCESS;
657     }
658     StoreMetaDataLocal oldLocal;
659     MetaDataManager::GetInstance().LoadMeta(meta.GetKeyLocal(), oldLocal, true);
660     // when user is 0, old store no "isPublic" attr, as well as new store's "isPublic" is true, do not intercept.
661     if (old.storeType != meta.storeType || Constant::NotEqual(old.isEncrypt, meta.isEncrypt) || old.area != meta.area ||
662         !options.persistent || (meta.securityLevel != NO_LABEL && (old.securityLevel > meta.securityLevel)) ||
663         (Constant::NotEqual(oldLocal.isPublic, options.isPublic) &&
664             (old.user != DEFAULT_USER_ID || !options.isPublic))) {
665         ZLOGE("meta appId:%{public}s storeId:%{public}s user:%{public}s type:%{public}d->%{public}d "
666               "encrypt:%{public}d->%{public}d area:%{public}d->%{public}d persistent:%{public}d "
667               "securityLevel:%{public}d->%{public}d isPublic:%{public}d->%{public}d",
668               appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str(), old.user.c_str(), old.storeType,
669               meta.storeType, old.isEncrypt, meta.isEncrypt, old.area, meta.area, options.persistent,
670               old.securityLevel, meta.securityLevel, oldLocal.isPublic, options.isPublic);
671         return Status::STORE_META_CHANGED;
672     }
673 
674     if (options.cloudConfig.enableCloud && !meta.enableCloud && executors_ != nullptr) {
675         DistributedData::StoreInfo storeInfo;
676         storeInfo.bundleName = appId.appId;
677         storeInfo.instanceId = GetInstIndex(storeInfo.tokenId, appId);
678         storeInfo.user = std::atoi(meta.user.c_str());
679         executors_->Execute([storeInfo]() {
680             auto event = std::make_unique<CloudEvent>(CloudEvent::GET_SCHEMA, storeInfo);
681             EventCenter::GetInstance().PostEvent(move(event));
682         });
683     }
684 
685     auto dbStatus = DBStatus::OK;
686     if (old != meta) {
687         dbStatus = Upgrade::GetInstance().ExportStore(old, meta);
688     }
689     return dbStatus == DBStatus::OK ? SUCCESS : DB_ERROR;
690 }
691 
AfterCreate(const AppId & appId,const StoreId & storeId,const Options & options,const std::vector<uint8_t> & password)692 Status KVDBServiceImpl::AfterCreate(const AppId &appId, const StoreId &storeId, const Options &options,
693     const std::vector<uint8_t> &password)
694 {
695     if (!appId.IsValid() || !storeId.IsValid() || !options.IsValidType()) {
696         ZLOGE("failed please check type:%{public}d appId:%{public}s storeId:%{public}s dataType:%{public}d",
697             options.kvStoreType, appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str(), options.dataType);
698         return INVALID_ARGUMENT;
699     }
700 
701     StoreMetaData metaData = GetStoreMetaData(appId, storeId);
702     AddOptions(options, metaData);
703 
704     StoreMetaData oldMeta;
705     auto isCreated = MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), oldMeta, true);
706     Status status = SUCCESS;
707     if (isCreated && oldMeta != metaData) {
708         auto dbStatus = Upgrade::GetInstance().UpdateStore(oldMeta, metaData, password);
709         ZLOGI("update status:%{public}d appId:%{public}s storeId:%{public}s inst:%{public}d "
710               "type:%{public}d->%{public}d dir:%{public}s dataType:%{public}d->%{public}d",
711             dbStatus, appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str(), metaData.instanceId,
712             oldMeta.storeType, metaData.storeType, metaData.dataDir.c_str(), oldMeta.dataType, metaData.dataType);
713         if (dbStatus != DBStatus::OK) {
714             status = STORE_UPGRADE_FAILED;
715         }
716     }
717 
718     if (!isCreated || oldMeta != metaData) {
719         if (!CheckerManager::GetInstance().IsDistrust(Converter::ConvertToStoreInfo(metaData))) {
720             MetaDataManager::GetInstance().SaveMeta(metaData.GetKey(), metaData);
721         }
722         MetaDataManager::GetInstance().SaveMeta(metaData.GetKey(), metaData, true);
723     }
724     AppIDMetaData appIdMeta;
725     appIdMeta.bundleName = metaData.bundleName;
726     appIdMeta.appId = metaData.appId;
727     MetaDataManager::GetInstance().SaveMeta(appIdMeta.GetKey(), appIdMeta, true);
728     SaveLocalMetaData(options, metaData);
729     Upgrade::GetInstance().UpdatePassword(metaData, password);
730     ZLOGI("appId:%{public}s storeId:%{public}s instanceId:%{public}d type:%{public}d dir:%{public}s "
731         "isCreated:%{public}d dataType:%{public}d", appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str(),
732         metaData.instanceId, metaData.storeType, metaData.dataDir.c_str(), isCreated, metaData.dataType);
733     return status;
734 }
735 
OnAppExit(pid_t uid,pid_t pid,uint32_t tokenId,const std::string & appId)736 int32_t KVDBServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &appId)
737 {
738     ZLOGI("pid:%{public}d uid:%{public}d appId:%{public}s", pid, uid, appId.c_str());
739     CheckerManager::StoreInfo info;
740     info.uid = uid;
741     info.tokenId = tokenId;
742     info.bundleName = appId;
743     syncAgents_.EraseIf([pid, &info](auto &key, SyncAgent &agent) {
744         if (agent.pid_ != pid) {
745             return false;
746         }
747         if (CheckerManager::GetInstance().IsSwitches(info)) {
748             MetaDataManager::GetInstance().Unsubscribe(SwitchesMetaData::GetPrefix({}));
749         }
750         agent.watchers_.clear();
751         auto stores = AutoCache::GetInstance().GetStoresIfPresent(key);
752         for (auto store : stores) {
753             if (store != nullptr) {
754                 store->UnregisterDetailProgressObserver();
755             }
756         }
757         return true;
758     });
759     return SUCCESS;
760 }
761 
CompareTripleIdentifier(const std::string & accountId,const std::string & identifier,const StoreMetaData & storeMeta)762 bool KVDBServiceImpl::CompareTripleIdentifier(const std::string &accountId, const std::string &identifier,
763     const StoreMetaData &storeMeta)
764 {
765     std::vector<std::string> accountIds { accountId, "ohosAnonymousUid", "default" };
766     for (auto &id : accountIds) {
767         auto convertedIds =
768             AppIdMappingConfigManager::GetInstance().Convert(storeMeta.appId, storeMeta.user);
769         const std::string &tempTripleIdentifier =
770             DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(id, convertedIds.first,
771                 storeMeta.storeId, false);
772         if (tempTripleIdentifier == identifier) {
773             ZLOGI("find triple identifier,storeId:%{public}s,id:%{public}s",
774                 Anonymous::Change(storeMeta.storeId).c_str(), Anonymous::Change(id).c_str());
775             return true;
776         }
777     }
778     return false;
779 }
780 
ResolveAutoLaunch(const std::string & identifier,DBLaunchParam & param)781 int32_t KVDBServiceImpl::ResolveAutoLaunch(const std::string &identifier, DBLaunchParam &param)
782 {
783     ZLOGI("user:%{public}s appId:%{public}s storeId:%{public}s identifier:%{public}s", param.userId.c_str(),
784         param.appId.c_str(), Anonymous::Change(param.storeId).c_str(), Anonymous::Change(identifier).c_str());
785 
786     std::vector<StoreMetaData> metaData;
787     auto prefix = StoreMetaData::GetPrefix({ DMAdapter::GetInstance().GetLocalDevice().uuid });
788     if (!MetaDataManager::GetInstance().LoadMeta(prefix, metaData)) {
789         ZLOGE("no meta data appId:%{public}s", param.appId.c_str());
790         return STORE_NOT_FOUND;
791     }
792 
793     auto accountId = AccountDelegate::GetInstance()->GetUnencryptedAccountId();
794     for (const auto &storeMeta : metaData) {
795         if (storeMeta.storeType < StoreMetaData::StoreType::STORE_KV_BEGIN ||
796             storeMeta.storeType > StoreMetaData::StoreType::STORE_KV_END ||
797             (!param.userId.empty() && (param.userId != storeMeta.user)) ||
798             storeMeta.appId == DistributedData::Bootstrap::GetInstance().GetProcessLabel()) {
799             continue;
800         }
801         auto identifierTag = DBManager::GetKvStoreIdentifier("", storeMeta.appId, storeMeta.storeId, true);
802         bool isTripleIdentifierEqual = CompareTripleIdentifier(accountId, identifier, storeMeta);
803         if (identifier != identifierTag && !isTripleIdentifierEqual) {
804             continue;
805         }
806         auto watchers = GetWatchers(storeMeta.tokenId, storeMeta.storeId);
807         auto store = AutoCache::GetInstance().GetStore(storeMeta, watchers);
808         if (isTripleIdentifierEqual && store != nullptr) {
809             store->SetEqualIdentifier(storeMeta.appId, storeMeta.storeId, accountId);
810         }
811 
812         ZLOGI("isTriple:%{public}d,storeId:%{public}s,appId:%{public}s,size:%{public}zu,user:%{public}s",
813             isTripleIdentifierEqual, Anonymous::Change(storeMeta.storeId).c_str(), storeMeta.appId.c_str(),
814             watchers.size(), storeMeta.user.c_str());
815     }
816     return SUCCESS;
817 }
818 
OnUserChange(uint32_t code,const std::string & user,const std::string & account)819 int32_t KVDBServiceImpl::OnUserChange(uint32_t code, const std::string &user, const std::string &account)
820 {
821     (void)code;
822     (void)user;
823     (void)account;
824     std::vector<int32_t> users;
825     AccountDelegate::GetInstance()->QueryUsers(users);
826     std::set<int32_t> userIds(users.begin(), users.end());
827     AutoCache::GetInstance().CloseExcept(userIds);
828     return SUCCESS;
829 }
830 
IsRemoteChange(const StoreMetaData & metaData,const std::string & device)831 bool KVDBServiceImpl::IsRemoteChange(const StoreMetaData &metaData, const std::string &device)
832 {
833     auto code = DeviceMatrix::GetInstance().GetCode(metaData);
834     if (code == DeviceMatrix::INVALID_MASK) {
835         return true;
836     }
837     auto [dynamic, statics] = DeviceMatrix::GetInstance().IsConsistent(device);
838     if (metaData.dataType == DataType::TYPE_STATICS && statics) {
839         return false;
840     }
841     if (metaData.dataType == DataType::TYPE_DYNAMICAL && dynamic) {
842         return false;
843     }
844     auto [exist, mask] = DeviceMatrix::GetInstance().GetRemoteMask(
845         device, static_cast<DeviceMatrix::LevelType>(metaData.dataType));
846     return (mask & code) == code;
847 }
848 
AddOptions(const Options & options,StoreMetaData & metaData)849 void KVDBServiceImpl::AddOptions(const Options &options, StoreMetaData &metaData)
850 {
851     metaData.isAutoSync = options.autoSync;
852     metaData.isBackup = options.backup;
853     metaData.isEncrypt = options.encrypt;
854     metaData.storeType = options.kvStoreType;
855     metaData.securityLevel = options.securityLevel;
856     metaData.area = options.area;
857     metaData.appId = CheckerManager::GetInstance().GetAppId(Converter::ConvertToStoreInfo(metaData));
858     metaData.appType = "harmony";
859     metaData.hapName = options.hapName;
860     if (metaData.appId == PASTEBOARD_SERVICE) {
861         auto userId = metaData.user;
862         metaData.user = PASTEBOARD_USER_ID;
863         metaData.dataDir = DirectoryManager::GetInstance().GetStorePath(metaData);
864         metaData.user = userId;
865     } else {
866         metaData.dataDir = DirectoryManager::GetInstance().GetStorePath(metaData);
867     }
868     metaData.schema = options.schema;
869     metaData.account = AccountDelegate::GetInstance()->GetCurrentAccountId();
870     metaData.isNeedCompress = options.isNeedCompress;
871     metaData.dataType = options.dataType;
872     metaData.enableCloud = options.cloudConfig.enableCloud;
873     metaData.cloudAutoSync = options.cloudConfig.autoSync;
874     metaData.authType = static_cast<int32_t>(options.authType);
875 }
876 
SaveLocalMetaData(const Options & options,const StoreMetaData & metaData)877 void KVDBServiceImpl::SaveLocalMetaData(const Options &options, const StoreMetaData &metaData)
878 {
879     StoreMetaDataLocal localMetaData;
880     localMetaData.isAutoSync = options.autoSync;
881     localMetaData.isBackup = options.backup;
882     localMetaData.isEncrypt = options.encrypt;
883     localMetaData.dataDir = DirectoryManager::GetInstance().GetStorePath(metaData);
884     localMetaData.schema = options.schema;
885     localMetaData.isPublic = options.isPublic;
886     for (auto &policy : options.policies) {
887         OHOS::DistributedData::PolicyValue value;
888         value.type = policy.type;
889         value.index = policy.value.index();
890         if (const uint32_t *pval = std::get_if<uint32_t>(&policy.value)) {
891             value.valueUint = *pval;
892         }
893         localMetaData.policies.emplace_back(value);
894     }
895     MetaDataManager::GetInstance().SaveMeta(metaData.GetKeyLocal(), localMetaData, true);
896 }
897 
GetStoreMetaData(const AppId & appId,const StoreId & storeId)898 StoreMetaData KVDBServiceImpl::GetStoreMetaData(const AppId &appId, const StoreId &storeId)
899 {
900     StoreMetaData metaData;
901     metaData.uid = IPCSkeleton::GetCallingUid();
902     metaData.tokenId = IPCSkeleton::GetCallingTokenID();
903     metaData.instanceId = GetInstIndex(metaData.tokenId, appId);
904     metaData.bundleName = appId.appId;
905     metaData.deviceId = DMAdapter::GetInstance().GetLocalDevice().uuid;
906     metaData.storeId = storeId.storeId;
907     auto user = AccountDelegate::GetInstance()->GetUserByToken(metaData.tokenId);
908     metaData.user = std::to_string(user);
909     return metaData;
910 }
911 
GetStrategyMeta(const AppId & appId,const StoreId & storeId)912 StrategyMeta KVDBServiceImpl::GetStrategyMeta(const AppId &appId, const StoreId &storeId)
913 {
914     auto tokenId = IPCSkeleton::GetCallingTokenID();
915     auto userId = AccountDelegate::GetInstance()->GetUserByToken(tokenId);
916     auto deviceId = DMAdapter::GetInstance().GetLocalDevice().uuid;
917     StrategyMeta strategyMeta(deviceId, std::to_string(userId), appId.appId, storeId.storeId);
918     strategyMeta.instanceId = GetInstIndex(tokenId, appId);
919     return strategyMeta;
920 }
921 
GetInstIndex(uint32_t tokenId,const AppId & appId)922 int32_t KVDBServiceImpl::GetInstIndex(uint32_t tokenId, const AppId &appId)
923 {
924     if (AccessTokenKit::GetTokenTypeFlag(tokenId) != TOKEN_HAP) {
925         return 0;
926     }
927 
928     HapTokenInfo tokenInfo;
929     tokenInfo.instIndex = -1;
930     int errCode = AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo);
931     if (errCode != RET_SUCCESS) {
932         ZLOGE("GetHapTokenInfo error:%{public}d, tokenId:0x%{public}x appId:%{public}s", errCode, tokenId,
933             appId.appId.c_str());
934         return -1;
935     }
936     return tokenInfo.instIndex;
937 }
938 
HandleGenBriefDetails(const GenDetails & details)939 KVDBServiceImpl::DBResult KVDBServiceImpl::HandleGenBriefDetails(const GenDetails &details)
940 {
941     DBResult dbResults{};
942     for (const auto &[id, detail] : details) {
943         dbResults[id] = DBStatus(detail.code);
944     }
945     return dbResults;
946 }
947 
DoCloudSync(const StoreMetaData & meta,const SyncInfo & syncInfo)948 Status KVDBServiceImpl::DoCloudSync(const StoreMetaData &meta, const SyncInfo &syncInfo)
949 {
950     if (!meta.enableCloud) {
951         ZLOGE("appId:%{public}s storeId:%{public}s instanceId:%{public}d not supports cloud sync", meta.appId.c_str(),
952             Anonymous::Change(meta.storeId).c_str(), meta.instanceId);
953         return Status::NOT_SUPPORT;
954     }
955     auto instance = CloudServer::GetInstance();
956     if (instance == nullptr) {
957         return Status::CLOUD_DISABLED;
958     }
959     if (!DMAdapter::GetInstance().IsNetworkAvailable()) {
960         return Status::NETWORK_ERROR;
961     }
962     std::vector<int32_t> users;
963     if (meta.user != StoreMetaData::ROOT_USER) {
964         users.push_back(std::atoi(meta.user.c_str()));
965     } else if (!AccountDelegate::GetInstance()->QueryForegroundUsers(users)) {
966         ZLOGE("appId:%{public}s storeId:%{public}s instanceId:%{public}d. no foreground user!", meta.appId.c_str(),
967             Anonymous::Change(meta.storeId).c_str(), meta.instanceId);
968         return Status::CLOUD_DISABLED;
969     }
970     bool res = false;
971     for (auto user : users) {
972         res = instance->IsSupportCloud(user) || res;
973     }
974     if (!res) {
975         return Status::CLOUD_DISABLED;
976     }
977 
978     DistributedData::StoreInfo storeInfo;
979     storeInfo.bundleName = meta.bundleName;
980     storeInfo.user = atoi(meta.user.c_str());
981     storeInfo.tokenId = meta.tokenId;
982     storeInfo.storeName = meta.storeId;
983     GenAsync syncCallback = [tokenId = storeInfo.tokenId, seqId = syncInfo.seqId, this](const GenDetails &details) {
984         OnAsyncComplete(tokenId, seqId, HandleGenDetails(details));
985     };
986     auto mixMode = static_cast<int32_t>(GeneralStore::MixMode(GeneralStore::CLOUD_TIME_FIRST,
987         meta.isAutoSync ? GeneralStore::AUTO_SYNC_MODE : GeneralStore::MANUAL_SYNC_MODE));
988     auto info = ChangeEvent::EventInfo({ mixMode, 0, false, syncInfo.triggerMode }, false, nullptr, syncCallback);
989     auto evt = std::make_unique<ChangeEvent>(std::move(storeInfo), std::move(info));
990     EventCenter::GetInstance().PostEvent(std::move(evt));
991     return SUCCESS;
992 }
993 
DoSync(const StoreMetaData & meta,const SyncInfo & info,const SyncEnd & complete,int32_t type)994 Status KVDBServiceImpl::DoSync(const StoreMetaData &meta, const SyncInfo &info, const SyncEnd &complete, int32_t type)
995 {
996     ZLOGD("seqId:0x%{public}" PRIx64 " type:%{public}d remote:%{public}zu appId:%{public}s storeId:%{public}s",
997         info.seqId, type, info.devices.size(), meta.bundleName.c_str(), Anonymous::Change(meta.storeId).c_str());
998     auto uuids = ConvertDevices(info.devices);
999     if (uuids.empty()) {
1000         ZLOGW("no device online seqId:0x%{public}" PRIx64 " remote:%{public}zu appId:%{public}s storeId:%{public}s",
1001             info.seqId, info.devices.size(), meta.bundleName.c_str(), Anonymous::Change(meta.storeId).c_str());
1002         return Status::ERROR;
1003     }
1004 
1005     return DoSyncBegin(uuids, meta, info, complete, type);
1006 }
1007 
DoSyncInOrder(const StoreMetaData & meta,const SyncInfo & info,const SyncEnd & complete,int32_t type)1008 Status KVDBServiceImpl::DoSyncInOrder(
1009     const StoreMetaData &meta, const SyncInfo &info, const SyncEnd &complete, int32_t type)
1010 {
1011     ZLOGD("type:%{public}d seqId:0x%{public}" PRIx64 " remote:%{public}zu appId:%{public}s storeId:%{public}s", type,
1012         info.seqId, info.devices.size(), meta.bundleName.c_str(), Anonymous::Change(meta.storeId).c_str());
1013     auto uuids = ConvertDevices(info.devices);
1014     if (uuids.empty()) {
1015         ZLOGW("no device seqId:0x%{public}" PRIx64 " remote:%{public}zu appId:%{public}s storeId:%{public}s",
1016             info.seqId, info.devices.size(), meta.bundleName.c_str(), Anonymous::Change(meta.storeId).c_str());
1017         return Status::DEVICE_NOT_ONLINE;
1018     }
1019     if (IsNeedMetaSync(meta, uuids)) {
1020         auto recv = DeviceMatrix::GetInstance().GetRecvLevel(uuids[0],
1021             static_cast<DeviceMatrix::LevelType>(DataType::TYPE_DYNAMICAL));
1022         RADAR_REPORT(STANDARD_DEVICE_SYNC, STANDARD_META_SYNC, RADAR_START,
1023             SYNC_STORE_ID, Anonymous::Change(meta.storeId), SYNC_APP_ID, meta.bundleName, CONCURRENT_ID,
1024             std::to_string(info.syncId), DATA_TYPE, meta.dataType, WATER_VERSION, recv.second);
1025         auto result = MetaDataManager::GetInstance().Sync(
1026             uuids, [this, meta, info, complete, type](const auto &results) {
1027             RADAR_REPORT(STANDARD_DEVICE_SYNC, STANDARD_META_SYNC, RADAR_SUCCESS,
1028                 SYNC_STORE_ID, Anonymous::Change(meta.storeId), SYNC_APP_ID, meta.bundleName, CONCURRENT_ID,
1029                 std::to_string(info.syncId), DATA_TYPE, meta.dataType);
1030             auto ret = ProcessResult(results);
1031             if (ret.first.empty()) {
1032                 DoComplete(meta, info, RefCount(), ret.second);
1033                 return;
1034             }
1035             auto status = DoSyncBegin(ret.first, meta, info, complete, type);
1036             ZLOGD("data sync status:%{public}d appId:%{public}s, storeId:%{public}s",
1037                 static_cast<int32_t>(status), meta.bundleName.c_str(), Anonymous::Change(meta.storeId).c_str());
1038         });
1039         if (!result) {
1040             RADAR_REPORT(STANDARD_DEVICE_SYNC, STANDARD_META_SYNC, RADAR_FAILED, ERROR_CODE, Status::ERROR,
1041                 BIZ_STATE, END, SYNC_STORE_ID, Anonymous::Change(meta.storeId), SYNC_APP_ID, meta.bundleName,
1042                 CONCURRENT_ID, std::to_string(info.syncId), DATA_TYPE, meta.dataType);
1043         }
1044         return result ? Status::SUCCESS : Status::ERROR;
1045     }
1046     return DoSyncBegin(uuids, meta, info, complete, type);
1047 }
1048 
IsNeedMetaSync(const StoreMetaData & meta,const std::vector<std::string> & uuids)1049 bool KVDBServiceImpl::IsNeedMetaSync(const StoreMetaData &meta, const std::vector<std::string> &uuids)
1050 {
1051     bool isAfterMeta = false;
1052     for (const auto &uuid : uuids) {
1053         auto metaData = meta;
1054         metaData.deviceId = uuid;
1055         CapMetaData capMeta;
1056         auto capKey = CapMetaRow::GetKeyFor(uuid);
1057         auto devInfo = DMAdapter::GetInstance().GetDeviceInfo(uuid);
1058         if ((!MetaDataManager::GetInstance().LoadMeta(std::string(capKey.begin(), capKey.end()), capMeta) &&
1059             !(devInfo.osType != OH_OS_TYPE &&
1060             devInfo.deviceType == static_cast<uint32_t>(DistributedHardware::DmDeviceType::DEVICE_TYPE_CAR))) ||
1061             !MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData)) {
1062             isAfterMeta = true;
1063             break;
1064         }
1065         auto [exist, mask] = DeviceMatrix::GetInstance().GetRemoteMask(uuid);
1066         if ((mask & DeviceMatrix::META_STORE_MASK) == DeviceMatrix::META_STORE_MASK) {
1067             isAfterMeta = true;
1068             break;
1069         }
1070     }
1071     return isAfterMeta;
1072 }
1073 
GetDistributedDataMeta(const std::string & deviceId)1074 StoreMetaData KVDBServiceImpl::GetDistributedDataMeta(const std::string &deviceId)
1075 {
1076     StoreMetaData meta;
1077     meta.deviceId = deviceId;
1078     meta.bundleName = Bootstrap::GetInstance().GetProcessLabel();
1079     meta.storeId = Bootstrap::GetInstance().GetMetaDBName();
1080     meta.user = DEFAULT_USER_ID;
1081     if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta)) {
1082         ZLOGE("Load meta fail, device: %{public}s", Anonymous::Change(deviceId).c_str());
1083     }
1084     return meta;
1085 }
1086 
ProcessResult(const std::map<std::string,int32_t> & results)1087 KVDBServiceImpl::SyncResult KVDBServiceImpl::ProcessResult(const std::map<std::string, int32_t> &results)
1088 {
1089     std::map<std::string, DBStatus> dbResults;
1090     std::vector<std::string> devices;
1091     for (const auto &[uuid, status] : results) {
1092         dbResults.insert_or_assign(uuid, static_cast<DBStatus>(status));
1093         if (static_cast<DBStatus>(status) != DBStatus::OK) {
1094             continue;
1095         }
1096         DeviceMatrix::GetInstance().OnExchanged(uuid, DeviceMatrix::META_STORE_MASK);
1097         devices.emplace_back(uuid);
1098     }
1099     ZLOGD("meta sync finish, total size:%{public}zu, success size:%{public}zu", dbResults.size(), devices.size());
1100     return { devices, dbResults };
1101 }
1102 
DoSyncBegin(const std::vector<std::string> & devices,const StoreMetaData & meta,const SyncInfo & info,const SyncEnd & complete,int32_t type)1103 Status KVDBServiceImpl::DoSyncBegin(const std::vector<std::string> &devices, const StoreMetaData &meta,
1104     const SyncInfo &info, const SyncEnd &complete, int32_t type)
1105 {
1106     if (devices.empty()) {
1107         return Status::INVALID_ARGUMENT;
1108     }
1109     auto watcher = GetWatchers(meta.tokenId, meta.storeId);
1110     RADAR_REPORT(STANDARD_DEVICE_SYNC, OPEN_STORE, RADAR_START, SYNC_STORE_ID, Anonymous::Change(meta.storeId),
1111         SYNC_APP_ID, meta.bundleName, CONCURRENT_ID, info.syncId, DATA_TYPE, meta.dataType);
1112     auto store = AutoCache::GetInstance().GetStore(meta, watcher);
1113     if (store == nullptr) {
1114         ZLOGE("GetStore failed! appId:%{public}s storeId:%{public}s storeId length:%{public}zu dir:%{public}s",
1115             meta.bundleName.c_str(), Anonymous::Change(meta.storeId).c_str(),
1116             meta.storeId.size(), meta.dataDir.c_str());
1117         RADAR_REPORT(STANDARD_DEVICE_SYNC, OPEN_STORE, RADAR_FAILED, ERROR_CODE, Status::ERROR, BIZ_STATE, END,
1118             SYNC_STORE_ID, Anonymous::Change(meta.storeId), SYNC_APP_ID, meta.bundleName, CONCURRENT_ID,
1119             std::to_string(info.syncId), DATA_TYPE, meta.dataType);
1120         return Status::ERROR;
1121     }
1122     RADAR_REPORT(STANDARD_DEVICE_SYNC, OPEN_STORE, RADAR_SUCCESS, SYNC_STORE_ID, Anonymous::Change(meta.storeId),
1123         SYNC_APP_ID, meta.bundleName, CONCURRENT_ID, std::to_string(info.syncId), DATA_TYPE, meta.dataType);
1124     KVDBQuery query(info.query);
1125     if (!query.IsValidQuery()) {
1126         ZLOGE("failed DBQuery:%{public}s", Anonymous::Change(info.query).c_str());
1127         return Status::INVALID_ARGUMENT;
1128     }
1129     auto mode = ConvertGeneralSyncMode(SyncMode(info.mode), SyncAction(type));
1130     if (GeneralStore::GetSyncMode(mode) < KVDBGeneralStore::NEARBY_END) {
1131         store->SetEqualIdentifier(meta.appId, meta.storeId);
1132     }
1133     SyncParam syncParam{};
1134     syncParam.mode = mode;
1135     RADAR_REPORT(STANDARD_DEVICE_SYNC, START_SYNC, RADAR_START, SYNC_STORE_ID, Anonymous::Change(meta.storeId),
1136         SYNC_APP_ID, meta.bundleName, CONCURRENT_ID, std::to_string(info.syncId), DATA_TYPE, meta.dataType);
1137     auto ret = store->Sync(
1138         devices, query,
1139         [this, complete](const GenDetails &result) mutable {
1140             auto deviceStatus = HandleGenBriefDetails(result);
1141             complete(deviceStatus);
1142         },
1143         syncParam);
1144     auto status = Status(ret.first);
1145     if (status != Status::SUCCESS) {
1146         RADAR_REPORT(STANDARD_DEVICE_SYNC, START_SYNC, RADAR_FAILED, ERROR_CODE, status, BIZ_STATE, END,
1147             SYNC_STORE_ID, Anonymous::Change(meta.storeId), SYNC_APP_ID, meta.bundleName, CONCURRENT_ID,
1148             std::to_string(info.syncId), DATA_TYPE, meta.dataType);
1149     } else {
1150         RADAR_REPORT(STANDARD_DEVICE_SYNC, START_SYNC, RADAR_SUCCESS, SYNC_STORE_ID, Anonymous::Change(meta.storeId),
1151             SYNC_APP_ID, meta.bundleName, CONCURRENT_ID, std::to_string(info.syncId), DATA_TYPE, meta.dataType);
1152     }
1153     return status;
1154 }
1155 
DoComplete(const StoreMetaData & meta,const SyncInfo & info,RefCount refCount,const DBResult & dbResult)1156 Status KVDBServiceImpl::DoComplete(const StoreMetaData &meta, const SyncInfo &info, RefCount refCount,
1157     const DBResult &dbResult)
1158 {
1159     ZLOGD("seqId:0x%{public}" PRIx64 " tokenId:0x%{public}x remote:%{public}zu", info.seqId, meta.tokenId,
1160         dbResult.size());
1161     std::map<std::string, Status> result;
1162     if (AccessTokenKit::GetTokenTypeFlag(meta.tokenId) != TOKEN_HAP) {
1163         for (auto &[key, status] : dbResult) {
1164             result[key] = ConvertDbStatusNative(status);
1165         }
1166     } else {
1167         for (auto &[key, status] : dbResult) {
1168             result[key] = ConvertDbStatus(status);
1169         }
1170     }
1171     bool success = true;
1172     for (auto &[key, status] : result) {
1173         if (status != SUCCESS) {
1174             success = false;
1175             RADAR_REPORT(STANDARD_DEVICE_SYNC, FINISH_SYNC, RADAR_FAILED, ERROR_CODE, status, BIZ_STATE, END,
1176                 SYNC_STORE_ID, Anonymous::Change(meta.storeId), SYNC_APP_ID, meta.bundleName, CONCURRENT_ID,
1177                 std::to_string(info.syncId), DATA_TYPE, meta.dataType);
1178             break;
1179         }
1180     }
1181     if (success) {
1182         RADAR_REPORT(STANDARD_DEVICE_SYNC, FINISH_SYNC, RADAR_SUCCESS, BIZ_STATE, END,
1183             SYNC_STORE_ID, Anonymous::Change(meta.storeId), SYNC_APP_ID, meta.bundleName, CONCURRENT_ID,
1184             std::to_string(info.syncId), DATA_TYPE, meta.dataType);
1185     }
1186     for (const auto &device : info.devices) {
1187         auto it = result.find(device);
1188         if (it != result.end() && it->second == SUCCESS) {
1189             DeviceMatrix::GetInstance().OnExchanged(device, meta, ConvertType(static_cast<SyncMode>(info.mode)));
1190         }
1191     }
1192     if (info.seqId == std::numeric_limits<uint64_t>::max()) {
1193         return SUCCESS;
1194     }
1195     sptr<IKVDBNotifier> notifier;
1196     syncAgents_.ComputeIfPresent(meta.tokenId, [&notifier](auto &key, SyncAgent &agent) {
1197         notifier = agent.notifier_;
1198         return true;
1199     });
1200     if (notifier == nullptr) {
1201         return SUCCESS;
1202     }
1203     notifier->SyncCompleted(result, info.seqId);
1204     return SUCCESS;
1205 }
1206 
ConvertDbStatusNative(DBStatus status)1207 Status KVDBServiceImpl::ConvertDbStatusNative(DBStatus status)
1208 {
1209     auto innerStatus = static_cast<int32_t>(status);
1210     if (innerStatus < 0) {
1211         return static_cast<Status>(status);
1212     } else if (status == DBStatus::COMM_FAILURE) {
1213         return Status::DEVICE_NOT_ONLINE;
1214     } else {
1215         return ConvertDbStatus(status);
1216     }
1217 }
1218 
GetSyncDelayTime(uint32_t delay,const StoreId & storeId)1219 uint32_t KVDBServiceImpl::GetSyncDelayTime(uint32_t delay, const StoreId &storeId)
1220 {
1221     if (delay != 0) {
1222         return std::min(std::max(delay, KvStoreSyncManager::SYNC_MIN_DELAY_MS), KvStoreSyncManager::SYNC_MAX_DELAY_MS);
1223     }
1224 
1225     bool isBackground = Constant::IsBackground(IPCSkeleton::GetCallingPid());
1226     if (!isBackground) {
1227         return delay;
1228     }
1229     delay = KvStoreSyncManager::SYNC_DEFAULT_DELAY_MS;
1230     syncAgents_.ComputeIfPresent(IPCSkeleton::GetCallingTokenID(), [&delay, &storeId](auto &, SyncAgent &agent) {
1231         auto it = agent.delayTimes_.find(storeId);
1232         if (it != agent.delayTimes_.end() && it->second != 0) {
1233             delay = it->second;
1234         }
1235         return true;
1236     });
1237     return delay;
1238 }
1239 
ConvertDbStatus(DBStatus status) const1240 Status KVDBServiceImpl::ConvertDbStatus(DBStatus status) const
1241 {
1242     switch (status) {
1243         case DBStatus::BUSY: // fallthrough
1244         case DBStatus::DB_ERROR:
1245             return Status::DB_ERROR;
1246         case DBStatus::OK:
1247             return Status::SUCCESS;
1248         case DBStatus::INVALID_ARGS:
1249             return Status::INVALID_ARGUMENT;
1250         case DBStatus::NOT_FOUND:
1251             return Status::KEY_NOT_FOUND;
1252         case DBStatus::INVALID_VALUE_FIELDS:
1253             return Status::INVALID_VALUE_FIELDS;
1254         case DBStatus::INVALID_FIELD_TYPE:
1255             return Status::INVALID_FIELD_TYPE;
1256         case DBStatus::CONSTRAIN_VIOLATION:
1257             return Status::CONSTRAIN_VIOLATION;
1258         case DBStatus::INVALID_FORMAT:
1259             return Status::INVALID_FORMAT;
1260         case DBStatus::INVALID_QUERY_FORMAT:
1261             return Status::INVALID_QUERY_FORMAT;
1262         case DBStatus::INVALID_QUERY_FIELD:
1263             return Status::INVALID_QUERY_FIELD;
1264         case DBStatus::NOT_SUPPORT:
1265             return Status::NOT_SUPPORT;
1266         case DBStatus::TIME_OUT:
1267             return Status::TIME_OUT;
1268         case DBStatus::OVER_MAX_LIMITS:
1269             return Status::OVER_MAX_LIMITS;
1270         case DBStatus::EKEYREVOKED_ERROR: // fallthrough
1271         case DBStatus::SECURITY_OPTION_CHECK_ERROR:
1272             return Status::SECURITY_LEVEL_ERROR;
1273         default:
1274             break;
1275     }
1276     return Status::ERROR;
1277 }
1278 
ConvertGeneralErr(GeneralError error) const1279 Status KVDBServiceImpl::ConvertGeneralErr(GeneralError error) const
1280 {
1281     switch (error) {
1282         case GeneralError::E_DB_ERROR:
1283             return Status::DB_ERROR;
1284         case GeneralError::E_OK:
1285             return Status::SUCCESS;
1286         case GeneralError::E_INVALID_ARGS:
1287             return Status::INVALID_ARGUMENT;
1288         case GeneralError::E_RECORD_NOT_FOUND:
1289             return Status::KEY_NOT_FOUND;
1290         case GeneralError::E_INVALID_VALUE_FIELDS:
1291             return Status::INVALID_VALUE_FIELDS;
1292         case GeneralError::E_INVALID_FIELD_TYPE:
1293             return Status::INVALID_FIELD_TYPE;
1294         case GeneralError::E_CONSTRAIN_VIOLATION:
1295             return Status::CONSTRAIN_VIOLATION;
1296         case GeneralError::E_INVALID_FORMAT:
1297             return Status::INVALID_FORMAT;
1298         case GeneralError::E_INVALID_QUERY_FORMAT:
1299             return Status::INVALID_QUERY_FORMAT;
1300         case GeneralError::E_INVALID_QUERY_FIELD:
1301             return Status::INVALID_QUERY_FIELD;
1302         case GeneralError::E_NOT_SUPPORT:
1303             return Status::NOT_SUPPORT;
1304         case GeneralError::E_TIME_OUT:
1305             return Status::TIME_OUT;
1306         case GeneralError::E_OVER_MAX_LIMITS:
1307             return Status::OVER_MAX_LIMITS;
1308         case GeneralError::E_SECURITY_LEVEL_ERROR:
1309             return Status::SECURITY_LEVEL_ERROR;
1310         default:
1311             break;
1312     }
1313     return Status::ERROR;
1314 }
1315 
ConvertDBMode(SyncMode syncMode) const1316 KVDBServiceImpl::DBMode KVDBServiceImpl::ConvertDBMode(SyncMode syncMode) const
1317 {
1318     DBMode dbMode;
1319     if (syncMode == SyncMode::PUSH) {
1320         dbMode = DBMode::SYNC_MODE_PUSH_ONLY;
1321     } else if (syncMode == SyncMode::PULL) {
1322         dbMode = DBMode::SYNC_MODE_PULL_ONLY;
1323     } else {
1324         dbMode = DBMode::SYNC_MODE_PUSH_PULL;
1325     }
1326     return dbMode;
1327 }
1328 
ConvertGeneralSyncMode(SyncMode syncMode,SyncAction syncAction) const1329 GeneralStore::SyncMode KVDBServiceImpl::ConvertGeneralSyncMode(SyncMode syncMode, SyncAction syncAction) const
1330 {
1331     GeneralStore::SyncMode generalSyncMode = GeneralStore::SyncMode::NEARBY_END;
1332     if (syncAction == SyncAction::ACTION_SUBSCRIBE) {
1333         generalSyncMode = GeneralStore::SyncMode::NEARBY_SUBSCRIBE_REMOTE;
1334     } else if (syncAction == SyncAction::ACTION_UNSUBSCRIBE) {
1335         generalSyncMode = GeneralStore::SyncMode::NEARBY_UNSUBSCRIBE_REMOTE;
1336     } else if (syncAction == SyncAction::ACTION_SYNC && syncMode == SyncMode::PUSH) {
1337         generalSyncMode = GeneralStore::SyncMode::NEARBY_PUSH;
1338     } else if (syncAction == SyncAction::ACTION_SYNC && syncMode == SyncMode::PULL) {
1339         generalSyncMode = GeneralStore::SyncMode::NEARBY_PULL;
1340     } else if (syncAction == SyncAction::ACTION_SYNC && syncMode == SyncMode::PUSH_PULL) {
1341         generalSyncMode = GeneralStore::SyncMode::NEARBY_PULL_PUSH;
1342     }
1343     return generalSyncMode;
1344 }
1345 
ConvertType(SyncMode syncMode) const1346 KVDBServiceImpl::ChangeType KVDBServiceImpl::ConvertType(SyncMode syncMode) const
1347 {
1348     switch (syncMode) {
1349         case SyncMode::PUSH:
1350             return ChangeType::CHANGE_LOCAL;
1351         case SyncMode::PULL:
1352             return ChangeType::CHANGE_REMOTE;
1353         case SyncMode::PUSH_PULL:
1354             return ChangeType::CHANGE_ALL;
1355         default:
1356             break;
1357     }
1358     return ChangeType::CHANGE_ALL;
1359 }
1360 
ConvertAction(Action action) const1361 SwitchState KVDBServiceImpl::ConvertAction(Action action) const
1362 {
1363     switch (action) {
1364         case Action::INSERT:
1365             return SwitchState::INSERT;
1366         case Action::UPDATE:
1367             return SwitchState::UPDATE;
1368         case Action::DELETE:
1369             return SwitchState::DELETE;
1370         default:
1371             break;
1372     }
1373     return SwitchState::INSERT;
1374 }
1375 
GetSyncMode(bool local,bool remote) const1376 SyncMode KVDBServiceImpl::GetSyncMode(bool local, bool remote) const
1377 {
1378     if (local && remote) {
1379         return SyncMode::PUSH_PULL;
1380     }
1381     if (local) {
1382         return SyncMode::PUSH;
1383     }
1384     if (remote) {
1385         return SyncMode::PULL;
1386     }
1387     return SyncMode::PUSH_PULL;
1388 }
1389 
ConvertDevices(const std::vector<std::string> & deviceIds) const1390 std::vector<std::string> KVDBServiceImpl::ConvertDevices(const std::vector<std::string> &deviceIds) const
1391 {
1392     if (deviceIds.empty()) {
1393         return DMAdapter::ToUUID(DMAdapter::GetInstance().GetRemoteDevices());
1394     }
1395     return DMAdapter::ToUUID(deviceIds);
1396 }
1397 
GetWatchers(uint32_t tokenId,const std::string & storeId)1398 AutoCache::Watchers KVDBServiceImpl::GetWatchers(uint32_t tokenId, const std::string &storeId)
1399 {
1400     AutoCache::Watchers watchers{};
1401     syncAgents_.ComputeIfPresent(tokenId, [&storeId, &watchers](auto &, SyncAgent &agent) {
1402         auto iter = agent.watchers_.find(storeId);
1403         if (iter != agent.watchers_.end()) {
1404             for (const auto &watcher : iter->second) {
1405                 watchers.insert(watcher);
1406             }
1407         }
1408         return true;
1409     });
1410     return watchers;
1411 }
1412 
ReInit(pid_t pid,const AppId & appId)1413 void KVDBServiceImpl::SyncAgent::ReInit(pid_t pid, const AppId &appId)
1414 {
1415     ZLOGW("pid:%{public}d->%{public}d appId:%{public}s notifier:%{public}d", pid, pid_,
1416         appId_.appId.c_str(), notifier_ == nullptr);
1417     pid_ = pid;
1418     appId_ = appId;
1419     notifier_ = nullptr;
1420     delayTimes_.clear();
1421     watchers_.clear();
1422 }
1423 
OnBind(const BindInfo & bindInfo)1424 int32_t KVDBServiceImpl::OnBind(const BindInfo &bindInfo)
1425 {
1426     executors_ = bindInfo.executors;
1427     KvStoreSyncManager::GetInstance()->SetThreadPool(bindInfo.executors);
1428     DeviceMatrix::GetInstance().SetExecutor(bindInfo.executors);
1429     return 0;
1430 }
1431 
OnInitialize()1432 int32_t KVDBServiceImpl::OnInitialize()
1433 {
1434     RegisterKvServiceInfo();
1435     RegisterHandler();
1436     Init();
1437     return SUCCESS;
1438 }
1439 
IsOHOSType(const std::vector<std::string> & ids)1440 bool KVDBServiceImpl::IsOHOSType(const std::vector<std::string> &ids)
1441 {
1442     if (ids.empty()) {
1443         ZLOGI("ids is empty");
1444         return true;
1445     }
1446     bool isOHOSType = true;
1447     for (auto &id : ids) {
1448         if (!DMAdapter::GetInstance().IsOHOSType(id)) {
1449             isOHOSType = false;
1450             break;
1451         }
1452     }
1453     return isOHOSType;
1454 }
1455 
RemoveDeviceData(const AppId & appId,const StoreId & storeId,const std::string & device)1456 Status KVDBServiceImpl::RemoveDeviceData(const AppId &appId, const StoreId &storeId, const std::string &device)
1457 {
1458     StoreMetaData metaData = GetStoreMetaData(appId, storeId);
1459     MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData);
1460     auto watcher = GetWatchers(metaData.tokenId, metaData.storeId);
1461     auto store = AutoCache::GetInstance().GetStore(metaData, watcher);
1462     if (store == nullptr) {
1463         ZLOGE("GetStore failed! appId:%{public}s storeId:%{public}s dir:%{public}s", metaData.bundleName.c_str(),
1464             Anonymous::Change(metaData.storeId).c_str(), metaData.dataDir.c_str());
1465         return Status::ERROR;
1466     }
1467 
1468     int32_t ret;
1469     if (device.empty()) {
1470         ret = store->Clean({}, KVDBGeneralStore::NEARBY_DATA, "");
1471     } else {
1472         ret = store->Clean({ DMAdapter::GetInstance().ToUUID(device) }, KVDBGeneralStore::NEARBY_DATA, "");
1473     }
1474     return ConvertGeneralErr(GeneralError(ret));
1475 }
1476 } // namespace OHOS::DistributedKv