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