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