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>> ¶ms)
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, ¬ifier](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 ¶m)
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, [¬ifier](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