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