1 /*
2 * Copyright (c) 2023-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 "SyncManager"
16 #include "sync_manager.h"
17
18 #include <chrono>
19
20 #include "account/account_delegate.h"
21 #include "bootstrap.h"
22 #include "checker/checker_manager.h"
23 #include "cloud/cloud_lock_event.h"
24 #include "cloud/cloud_report.h"
25 #include "cloud/cloud_server.h"
26 #include "cloud/schema_meta.h"
27 #include "cloud_value_util.h"
28 #include "device_manager_adapter.h"
29 #include "dfx_types.h"
30 #include "eventcenter/event_center.h"
31 #include "log_print.h"
32 #include "metadata/meta_data_manager.h"
33 #include "network/network_delegate.h"
34 #include "reporter.h"
35 #include "screen/screen_manager.h"
36 #include "sync_strategies/network_sync_strategy.h"
37 #include "user_delegate.h"
38 #include "utils/anonymous.h"
39 namespace OHOS::CloudData {
40 using namespace DistributedData;
41 using namespace DistributedDataDfx;
42 using namespace DistributedKv;
43 using namespace SharingUtil;
44 using namespace std::chrono;
45 using Account = OHOS::DistributedData::AccountDelegate;
46 using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter;
47 using Defer = EventCenter::Defer;
48 std::atomic<uint32_t> SyncManager::genId_ = 0;
49 constexpr int32_t SYSTEM_USER_ID = 0;
50 static constexpr const char *FT_GET_STORE = "GET_STORE";
51 static constexpr const char *FT_CALLBACK = "CALLBACK";
SyncInfo(int32_t user,const std::string & bundleName,const Store & store,const Tables & tables,int32_t triggerMode)52 SyncManager::SyncInfo::SyncInfo(
53 int32_t user, const std::string &bundleName, const Store &store, const Tables &tables, int32_t triggerMode)
54 : user_(user), bundleName_(bundleName), triggerMode_(triggerMode)
55 {
56 if (!store.empty()) {
57 tables_[store] = tables;
58 }
59 syncId_ = SyncManager::GenerateId(user);
60 }
61
SyncInfo(int32_t user,const std::string & bundleName,const Stores & stores)62 SyncManager::SyncInfo::SyncInfo(int32_t user, const std::string &bundleName, const Stores &stores)
63 : user_(user), bundleName_(bundleName)
64 {
65 for (auto &store : stores) {
66 tables_[store] = {};
67 }
68 syncId_ = SyncManager::GenerateId(user);
69 }
70
SyncInfo(int32_t user,const std::string & bundleName,const MutliStoreTables & tables)71 SyncManager::SyncInfo::SyncInfo(int32_t user, const std::string &bundleName, const MutliStoreTables &tables)
72 : user_(user), bundleName_(bundleName), tables_(tables)
73 {
74 tables_ = tables;
75 syncId_ = SyncManager::GenerateId(user);
76 }
77
SyncInfo(const Param & param)78 SyncManager::SyncInfo::SyncInfo(const Param ¶m)
79 : user_(param.user), bundleName_(param.bundleName), triggerMode_(param.triggerMode)
80 {
81 if (!param.store.empty()) {
82 tables_[param.store] = param.tables;
83 }
84 syncId_ = SyncManager::GenerateId(param.user);
85 prepareTraceId_ = param.prepareTraceId;
86 }
87
SetMode(int32_t mode)88 void SyncManager::SyncInfo::SetMode(int32_t mode)
89 {
90 mode_ = mode;
91 }
92
SetWait(int32_t wait)93 void SyncManager::SyncInfo::SetWait(int32_t wait)
94 {
95 wait_ = wait;
96 }
97
SetAsyncDetail(GenAsync asyncDetail)98 void SyncManager::SyncInfo::SetAsyncDetail(GenAsync asyncDetail)
99 {
100 async_ = std::move(asyncDetail);
101 }
102
SetQuery(std::shared_ptr<GenQuery> query)103 void SyncManager::SyncInfo::SetQuery(std::shared_ptr<GenQuery> query)
104 {
105 query_ = query;
106 }
107
SetCompensation(bool isCompensation)108 void SyncManager::SyncInfo::SetCompensation(bool isCompensation)
109 {
110 isCompensation_ = isCompensation;
111 }
112
SetTriggerMode(int32_t triggerMode)113 void SyncManager::SyncInfo::SetTriggerMode(int32_t triggerMode)
114 {
115 triggerMode_ = triggerMode;
116 }
117
SetError(int32_t code) const118 void SyncManager::SyncInfo::SetError(int32_t code) const
119 {
120 if (async_) {
121 GenDetails details;
122 auto &detail = details[id_];
123 detail.progress = GenProgress::SYNC_FINISH;
124 detail.code = code;
125 async_(std::move(details));
126 }
127 }
128
GenerateQuery(const std::string & store,const Tables & tables)129 std::shared_ptr<GenQuery> SyncManager::SyncInfo::GenerateQuery(const std::string &store, const Tables &tables)
130 {
131 if (query_ != nullptr) {
132 return query_;
133 }
134 class SyncQuery final : public GenQuery {
135 public:
136 explicit SyncQuery(const std::vector<std::string> &tables) : tables_(tables) {}
137
138 bool IsEqual(uint64_t tid) override
139 {
140 return false;
141 }
142
143 std::vector<std::string> GetTables() override
144 {
145 return tables_;
146 }
147
148 private:
149 std::vector<std::string> tables_;
150 };
151 auto it = tables_.find(store);
152 return std::make_shared<SyncQuery>(it == tables_.end() || it->second.empty() ? tables : it->second);
153 }
154
Contains(const std::string & storeName)155 bool SyncManager::SyncInfo::Contains(const std::string &storeName)
156 {
157 return tables_.empty() || tables_.find(storeName) != tables_.end();
158 }
159
GetLockChangeHandler()160 std::function<void(const Event &)> SyncManager::GetLockChangeHandler()
161 {
162 return [](const Event &event) {
163 auto &evt = static_cast<const CloudLockEvent &>(event);
164 auto storeInfo = evt.GetStoreInfo();
165 auto callback = evt.GetCallback();
166 if (callback == nullptr) {
167 ZLOGE("callback is nullptr. bundleName: %{public}s, storeName: %{public}s, user: %{public}d.",
168 storeInfo.bundleName.c_str(), Anonymous::Change(storeInfo.storeName).c_str(), storeInfo.user);
169 return;
170 }
171 CloudInfo cloud;
172 cloud.user = storeInfo.user;
173 SyncInfo info(storeInfo.user, storeInfo.bundleName);
174 auto code = IsValid(info, cloud);
175 if (code != E_OK) {
176 return;
177 }
178
179 StoreMetaData meta(storeInfo);
180 meta.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
181 if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true)) {
182 ZLOGE("not found meta. bundleName: %{public}s, storeName: %{public}s, user: %{public}d.",
183 storeInfo.bundleName.c_str(), Anonymous::Change(storeInfo.storeName).c_str(), storeInfo.user);
184 return;
185 }
186 auto [status, store] = GetStore(meta, storeInfo.user);
187 if (store == nullptr) {
188 ZLOGE("failed to get store. bundleName: %{public}s, storeName: %{public}s, user: %{public}d.",
189 storeInfo.bundleName.c_str(), Anonymous::Change(storeInfo.storeName).c_str(), storeInfo.user);
190 return;
191 }
192 if (evt.GetEventId() == CloudEvent::LOCK_CLOUD_CONTAINER) {
193 auto [result, expiredTime] = store->LockCloudDB();
194 callback(result, expiredTime);
195 } else {
196 auto result = store->UnLockCloudDB();
197 callback(result, 0);
198 }
199 };
200 }
201
SyncManager()202 SyncManager::SyncManager()
203 {
204 EventCenter::GetInstance().Subscribe(CloudEvent::LOCK_CLOUD_CONTAINER, GetLockChangeHandler());
205 EventCenter::GetInstance().Subscribe(CloudEvent::UNLOCK_CLOUD_CONTAINER, GetLockChangeHandler());
206 EventCenter::GetInstance().Subscribe(CloudEvent::LOCAL_CHANGE, GetClientChangeHandler());
207 syncStrategy_ = std::make_shared<NetworkSyncStrategy>();
208 auto metaName = Bootstrap::GetInstance().GetProcessLabel();
209 kvApps_.insert(std::move(metaName));
210 auto stores = CheckerManager::GetInstance().GetStaticStores();
211 for (auto &store : stores) {
212 kvApps_.insert(std::move(store.bundleName));
213 }
214 stores = CheckerManager::GetInstance().GetDynamicStores();
215 for (auto &store : stores) {
216 kvApps_.insert(std::move(store.bundleName));
217 }
218 }
219
~SyncManager()220 SyncManager::~SyncManager()
221 {
222 if (executor_ != nullptr) {
223 actives_.ForEachCopies([this](auto &syncId, auto &taskId) {
224 executor_->Remove(taskId);
225 return false;
226 });
227 executor_ = nullptr;
228 }
229 }
230
Bind(std::shared_ptr<ExecutorPool> executor)231 int32_t SyncManager::Bind(std::shared_ptr<ExecutorPool> executor)
232 {
233 executor_ = executor;
234 return E_OK;
235 }
236
DoCloudSync(SyncInfo syncInfo)237 int32_t SyncManager::DoCloudSync(SyncInfo syncInfo)
238 {
239 if (executor_ == nullptr) {
240 return E_NOT_INIT;
241 }
242 auto syncId = GenerateId(syncInfo.user_);
243 auto ref = GenSyncRef(syncId);
244 actives_.Compute(syncId, [this, &ref, &syncInfo](const uint64_t &key, TaskId &taskId) mutable {
245 taskId = executor_->Execute(GetSyncTask(0, true, ref, std::move(syncInfo)));
246 return true;
247 });
248 return E_OK;
249 }
250
StopCloudSync(int32_t user)251 int32_t SyncManager::StopCloudSync(int32_t user)
252 {
253 if (executor_ == nullptr) {
254 return E_NOT_INIT;
255 }
256 actives_.ForEachCopies([this, user](auto &syncId, auto &taskId) {
257 if (Compare(syncId, user) == 0) {
258 executor_->Remove(taskId);
259 }
260 return false;
261 });
262 return E_OK;
263 }
264
IsValid(SyncInfo & info,CloudInfo & cloud)265 GeneralError SyncManager::IsValid(SyncInfo &info, CloudInfo &cloud)
266 {
267 if (!MetaDataManager::GetInstance().LoadMeta(cloud.GetKey(), cloud, true) ||
268 (info.id_ != SyncInfo::DEFAULT_ID && cloud.id != info.id_)) {
269 info.SetError(E_CLOUD_DISABLED);
270 ZLOGE("cloudInfo invalid:%{public}d, <syncId:%{public}s, metaId:%{public}s>", cloud.IsValid(),
271 Anonymous::Change(info.id_).c_str(), Anonymous::Change(cloud.id).c_str());
272 return E_CLOUD_DISABLED;
273 }
274 if (!cloud.enableCloud || (!info.bundleName_.empty() && !cloud.IsOn(info.bundleName_))) {
275 info.SetError(E_CLOUD_DISABLED);
276 ZLOGD("enable:%{public}d, bundleName:%{public}s", cloud.enableCloud, info.bundleName_.c_str());
277 return E_CLOUD_DISABLED;
278 }
279 if (!NetworkDelegate::GetInstance()->IsNetworkAvailable()) {
280 info.SetError(E_NETWORK_ERROR);
281 ZLOGD("network unavailable");
282 return E_NETWORK_ERROR;
283 }
284 if (!Account::GetInstance()->IsVerified(info.user_)) {
285 info.SetError(E_USER_UNLOCK);
286 ZLOGD("user unverified");
287 return E_ERROR;
288 }
289 return E_OK;
290 }
291
GetPostEventTask(const std::vector<SchemaMeta> & schemas,CloudInfo & cloud,SyncInfo & info,bool retry,const TraceIds & traceIds)292 std::function<void()> SyncManager::GetPostEventTask(const std::vector<SchemaMeta> &schemas, CloudInfo &cloud,
293 SyncInfo &info, bool retry, const TraceIds &traceIds)
294 {
295 return [this, &cloud, &info, &schemas, retry, &traceIds]() {
296 bool isPostEvent = false;
297 auto syncId = info.syncId_;
298 for (auto &schema : schemas) {
299 auto it = traceIds.find(schema.bundleName);
300 if (!cloud.IsOn(schema.bundleName)) {
301 UpdateFinishSyncInfo({ cloud.user, cloud.id, schema.bundleName, "" }, syncId, E_ERROR);
302 Report({ cloud.user, schema.bundleName, it == traceIds.end() ? "" : it->second, SyncStage::END,
303 E_ERROR });
304 continue;
305 }
306 for (const auto &database : schema.databases) {
307 if (!info.Contains(database.name)) {
308 UpdateFinishSyncInfo({ cloud.user, cloud.id, schema.bundleName, database.name }, syncId, E_ERROR);
309 Report({ cloud.user, schema.bundleName, it == traceIds.end() ? "" : it->second, SyncStage::END,
310 E_ERROR });
311 continue;
312 }
313 StoreInfo storeInfo = { 0, schema.bundleName, database.name, cloud.apps[schema.bundleName].instanceId,
314 info.user_, "", syncId };
315 auto status = syncStrategy_->CheckSyncAction(storeInfo);
316 if (status != SUCCESS) {
317 ZLOGW("Verification strategy failed, status:%{public}d. %{public}d:%{public}s:%{public}s", status,
318 storeInfo.user, storeInfo.bundleName.c_str(), Anonymous::Change(storeInfo.storeName).c_str());
319 UpdateFinishSyncInfo({ cloud.user, cloud.id, schema.bundleName, database.name }, syncId, status);
320 Report({ cloud.user, schema.bundleName, it == traceIds.end() ? "" : it->second, SyncStage::END,
321 status });
322 info.SetError(status);
323 continue;
324 }
325 auto query = info.GenerateQuery(database.name, database.GetTableNames());
326 SyncParam syncParam = { info.mode_, info.wait_, info.isCompensation_, info.triggerMode_,
327 it == traceIds.end() ? "" : it->second, cloud.user };
328 auto evt = std::make_unique<SyncEvent>(std::move(storeInfo),
329 SyncEvent::EventInfo{ syncParam, retry, std::move(query), info.async_ });
330 EventCenter::GetInstance().PostEvent(std::move(evt));
331 isPostEvent = true;
332 }
333 }
334 if (!isPostEvent) {
335 ZLOGE("schema is invalid, user: %{public}d", cloud.user);
336 info.SetError(E_ERROR);
337 }
338 };
339 }
340
GetSyncTask(int32_t times,bool retry,RefCount ref,SyncInfo && syncInfo)341 ExecutorPool::Task SyncManager::GetSyncTask(int32_t times, bool retry, RefCount ref, SyncInfo &&syncInfo)
342 {
343 times++;
344 return [this, times, retry, keep = std::move(ref), info = std::move(syncInfo)]() mutable {
345 activeInfos_.Erase(info.syncId_);
346 bool createdByDefaultUser = InitDefaultUser(info.user_);
347 CloudInfo cloud;
348 cloud.user = info.user_;
349
350 auto cloudSyncInfos = GetCloudSyncInfo(info, cloud);
351 if (cloudSyncInfos.empty()) {
352 ZLOGD("get cloud info failed, user: %{public}d.", cloud.user);
353 info.SetError(E_CLOUD_DISABLED);
354 return;
355 }
356 auto traceIds = GetPrepareTraceId(info, cloud);
357 BatchReport(info.user_, traceIds, SyncStage::PREPARE, E_OK);
358 UpdateStartSyncInfo(cloudSyncInfos);
359 auto code = IsValid(info, cloud);
360 if (code != E_OK) {
361 BatchUpdateFinishState(cloudSyncInfos, code);
362 BatchReport(info.user_, traceIds, SyncStage::END, code);
363 return;
364 }
365
366 auto retryer = GetRetryer(times, info, cloud.user);
367 auto schemas = GetSchemaMeta(cloud, info.bundleName_);
368 if (schemas.empty()) {
369 UpdateSchema(info);
370 schemas = GetSchemaMeta(cloud, info.bundleName_);
371 if (schemas.empty()) {
372 auto it = traceIds.find(info.bundleName_);
373 retryer(RETRY_INTERVAL, E_RETRY_TIMEOUT, GenStore::CLOUD_ERR_OFFSET + E_CLOUD_DISABLED,
374 it == traceIds.end() ? "" : it->second);
375 BatchUpdateFinishState(cloudSyncInfos, E_CLOUD_DISABLED);
376 BatchReport(info.user_, traceIds, SyncStage::END, E_CLOUD_DISABLED);
377 return;
378 }
379 }
380 Defer defer(GetSyncHandler(std::move(retryer)), CloudEvent::CLOUD_SYNC);
381 if (createdByDefaultUser) {
382 info.user_ = 0;
383 }
384 auto task = GetPostEventTask(schemas, cloud, info, retry, traceIds);
385 task();
386 };
387 }
388
GetSyncHandler(Retryer retryer)389 std::function<void(const Event &)> SyncManager::GetSyncHandler(Retryer retryer)
390 {
391 return [this, retryer](const Event &event) {
392 auto &evt = static_cast<const SyncEvent &>(event);
393 auto &storeInfo = evt.GetStoreInfo();
394 GenAsync async = evt.GetAsyncDetail();
395 auto prepareTraceId = evt.GetPrepareTraceId();
396 auto user = evt.GetUser();
397 GenDetails details;
398 auto &detail = details[SyncInfo::DEFAULT_ID];
399 detail.progress = GenProgress::SYNC_FINISH;
400 auto [hasMeta, meta] = GetMetaData(storeInfo);
401 if (!hasMeta) {
402 return DoExceptionalCallback(async, details, storeInfo, prepareTraceId);
403 }
404 auto [code, store] = GetStore(meta, storeInfo.user);
405 if (code == E_SCREEN_LOCKED) {
406 AddCompensateSync(meta);
407 }
408 if (store == nullptr) {
409 ZLOGE("store null, storeId:%{public}s, prepareTraceId:%{public}s", meta.GetStoreAlias().c_str(),
410 prepareTraceId.c_str());
411 return DoExceptionalCallback(async, details, storeInfo, prepareTraceId);
412 }
413 if (!meta.enableCloud) {
414 ZLOGW("meta.enableCloud is false, storeId:%{public}s, prepareTraceId:%{public}s",
415 meta.GetStoreAlias().c_str(), prepareTraceId.c_str());
416 return DoExceptionalCallback(async, details, storeInfo, prepareTraceId, E_CLOUD_DISABLED);
417 }
418 ZLOGI("database:<%{public}d:%{public}s:%{public}s:%{public}s> sync start, asyncDownloadAsset?[%{public}d]",
419 storeInfo.user, storeInfo.bundleName.c_str(), meta.GetStoreAlias().c_str(), prepareTraceId.c_str(),
420 meta.asyncDownloadAsset);
421 ReportSyncEvent(evt, BizState::BEGIN, E_OK);
422 SyncParam syncParam = { evt.GetMode(), evt.GetWait(), evt.IsCompensation(), MODE_DEFAULT, prepareTraceId };
423 syncParam.asyncDownloadAsset = meta.asyncDownloadAsset;
424 auto [status, dbCode] = store->Sync({ SyncInfo::DEFAULT_ID }, *(evt.GetQuery()),
425 evt.AutoRetry() ? RetryCallback(storeInfo, retryer, evt.GetTriggerMode(), prepareTraceId, user)
426 : GetCallback(async, storeInfo, evt.GetTriggerMode(), prepareTraceId, user), syncParam);
427 if (status != E_OK) {
428 if (async) {
429 detail.code = status;
430 async(std::move(details));
431 }
432 UpdateFinishSyncInfo({ storeInfo.user, GetAccountId(storeInfo.user), storeInfo.bundleName,
433 storeInfo.storeName }, storeInfo.syncId, E_ERROR);
434 if (status != GeneralError::E_NOT_SUPPORT) {
435 auto code = dbCode == 0 ? GenStore::CLOUD_ERR_OFFSET + status : dbCode;
436 ReportSyncEvent(evt, BizState::END, code);
437 }
438 }
439 };
440 }
441
ReportSyncEvent(const SyncEvent & evt,BizState bizState,int32_t code)442 void SyncManager::ReportSyncEvent(const SyncEvent &evt, BizState bizState, int32_t code)
443 {
444 auto &storeInfo = evt.GetStoreInfo();
445 if (bizState == BizState::BEGIN) {
446 RadarReporter::Report({storeInfo.bundleName.c_str(), CLOUD_SYNC, TRIGGER_SYNC,
447 storeInfo.syncId, evt.GetTriggerMode()}, "GetSyncHandler", bizState);
448 } else {
449 RadarReporter::Report({storeInfo.bundleName.c_str(), CLOUD_SYNC, FINISH_SYNC,
450 storeInfo.syncId, evt.GetTriggerMode(), code}, "GetSyncHandler", bizState);
451 }
452 SyncStage syncStage = (bizState == BizState::BEGIN) ? SyncStage::START : SyncStage::END;
453 Report({evt.GetUser(), storeInfo.bundleName, evt.GetPrepareTraceId(), syncStage, code});
454 }
455
GetClientChangeHandler()456 std::function<void(const Event &)> SyncManager::GetClientChangeHandler()
457 {
458 return [this](const Event &event) {
459 auto &evt = static_cast<const SyncEvent &>(event);
460 auto store = evt.GetStoreInfo();
461 SyncInfo syncInfo(store.user, store.bundleName, store.storeName);
462 syncInfo.SetMode(evt.GetMode());
463 syncInfo.SetWait(evt.GetWait());
464 syncInfo.SetAsyncDetail(evt.GetAsyncDetail());
465 syncInfo.SetQuery(evt.GetQuery());
466 syncInfo.SetCompensation(evt.IsCompensation());
467 syncInfo.SetTriggerMode(evt.GetTriggerMode());
468 auto times = evt.AutoRetry() ? RETRY_TIMES - CLIENT_RETRY_TIMES : RETRY_TIMES;
469 executor_->Execute(GetSyncTask(times, evt.AutoRetry(), RefCount(), std::move(syncInfo)));
470 };
471 }
472
Report(const std::string & faultType,const std::string & bundleName,int32_t errCode,const std::string & appendix)473 void SyncManager::Report(
474 const std::string &faultType, const std::string &bundleName, int32_t errCode, const std::string &appendix)
475 {
476 ArkDataFaultMsg msg = { .faultType = faultType,
477 .bundleName = bundleName,
478 .moduleName = ModuleName::CLOUD_SERVER,
479 .errorType = errCode + GenStore::CLOUD_ERR_OFFSET,
480 .appendixMsg = appendix };
481 Reporter::GetInstance()->CloudSyncFault()->Report(msg);
482 }
483
GetRetryer(int32_t times,const SyncInfo & syncInfo,int32_t user)484 SyncManager::Retryer SyncManager::GetRetryer(int32_t times, const SyncInfo &syncInfo, int32_t user)
485 {
486 if (times >= RETRY_TIMES) {
487 return [this, user, info = SyncInfo(syncInfo)](Duration, int32_t code, int32_t dbCode,
488 const std::string &prepareTraceId) mutable {
489 if (code == E_OK || code == E_SYNC_TASK_MERGED) {
490 return true;
491 }
492 info.SetError(code);
493 RadarReporter::Report({ info.bundleName_.c_str(), CLOUD_SYNC, FINISH_SYNC, info.syncId_, info.triggerMode_,
494 dbCode },
495 "GetRetryer", BizState::END);
496 Report({ user, info.bundleName_, prepareTraceId, SyncStage::END,
497 dbCode == GenStore::DB_ERR_OFFSET ? 0 : dbCode });
498 Report(FT_CALLBACK, info.bundleName_, static_cast<int32_t>(Fault::CSF_GS_CLOUD_SYNC),
499 "code=" + std::to_string(code) + ",dbCode=" + std::to_string(static_cast<int32_t>(dbCode)));
500 return true;
501 };
502 }
503 return [this, times, user, info = SyncInfo(syncInfo)](Duration interval, int32_t code, int32_t dbCode,
504 const std::string &prepareTraceId) mutable {
505 if (code == E_OK || code == E_SYNC_TASK_MERGED) {
506 return true;
507 }
508 if (code == E_NO_SPACE_FOR_ASSET || code == E_RECODE_LIMIT_EXCEEDED) {
509 info.SetError(code);
510 RadarReporter::Report({ info.bundleName_.c_str(), CLOUD_SYNC, FINISH_SYNC, info.syncId_, info.triggerMode_,
511 dbCode },
512 "GetRetryer", BizState::END);
513 Report({ user, info.bundleName_, prepareTraceId, SyncStage::END,
514 dbCode == GenStore::DB_ERR_OFFSET ? 0 : dbCode });
515 Report(FT_CALLBACK, info.bundleName_, static_cast<int32_t>(Fault::CSF_GS_CLOUD_SYNC),
516 "code=" + std::to_string(code) + ",dbCode=" + std::to_string(static_cast<int32_t>(dbCode)));
517 return true;
518 }
519
520 activeInfos_.ComputeIfAbsent(info.syncId_, [this, times, interval, &info](uint64_t key) mutable {
521 auto syncId = GenerateId(info.user_);
522 auto ref = GenSyncRef(syncId);
523 actives_.Compute(syncId, [this, times, interval, &ref, &info](const uint64_t &key, TaskId &value) mutable {
524 value = executor_->Schedule(interval, GetSyncTask(times, true, ref, std::move(info)));
525 return true;
526 });
527 return syncId;
528 });
529 return true;
530 };
531 }
532
GenerateId(int32_t user)533 uint64_t SyncManager::GenerateId(int32_t user)
534 {
535 uint64_t syncId = static_cast<uint64_t>(user) & 0xFFFFFFFF;
536 return (syncId << MV_BIT) | (++genId_);
537 }
538
GenSyncRef(uint64_t syncId)539 RefCount SyncManager::GenSyncRef(uint64_t syncId)
540 {
541 return RefCount([syncId, this]() {
542 actives_.Erase(syncId);
543 });
544 }
545
Compare(uint64_t syncId,int32_t user)546 int32_t SyncManager::Compare(uint64_t syncId, int32_t user)
547 {
548 uint64_t inner = static_cast<uint64_t>(user) & 0xFFFFFFFF;
549 return (syncId & USER_MARK) == (inner << MV_BIT);
550 }
551
UpdateSchema(const SyncManager::SyncInfo & syncInfo)552 void SyncManager::UpdateSchema(const SyncManager::SyncInfo &syncInfo)
553 {
554 StoreInfo storeInfo;
555 storeInfo.user = syncInfo.user_;
556 storeInfo.bundleName = syncInfo.bundleName_;
557 EventCenter::GetInstance().PostEvent(std::make_unique<CloudEvent>(CloudEvent::GET_SCHEMA, storeInfo));
558 }
559
GetBindInfos(const StoreMetaData & meta,const std::vector<int32_t> & users,const Database & schemaDatabase)560 std::map<uint32_t, GeneralStore::BindInfo> SyncManager::GetBindInfos(const StoreMetaData &meta,
561 const std::vector<int32_t> &users, const Database &schemaDatabase)
562 {
563 auto instance = CloudServer::GetInstance();
564 if (instance == nullptr) {
565 ZLOGD("not support cloud sync");
566 return {};
567 }
568 std::map<uint32_t, GeneralStore::BindInfo> bindInfos;
569 for (auto &activeUser : users) {
570 if (activeUser == 0) {
571 continue;
572 }
573 auto cloudDB = instance->ConnectCloudDB(meta.bundleName, activeUser, schemaDatabase);
574 if (cloudDB == nullptr) {
575 ZLOGE("failed, no cloud DB <%{public}d:0x%{public}x %{public}s<->%{public}s>", meta.tokenId, activeUser,
576 Anonymous::Change(schemaDatabase.name).c_str(), Anonymous::Change(schemaDatabase.alias).c_str());
577 Report(FT_GET_STORE, meta.bundleName, static_cast<int32_t>(Fault::CSF_CONNECT_CLOUD_DB),
578 "ConnectCloudDB failed, database=" + schemaDatabase.name);
579 return {};
580 }
581 if (meta.storeType >= StoreMetaData::StoreType::STORE_KV_BEGIN &&
582 meta.storeType <= StoreMetaData::StoreType::STORE_KV_END) {
583 bindInfos.insert_or_assign(activeUser, GeneralStore::BindInfo{ std::move(cloudDB), nullptr });
584 continue;
585 }
586 auto assetLoader = instance->ConnectAssetLoader(meta.bundleName, activeUser, schemaDatabase);
587 if (assetLoader == nullptr) {
588 ZLOGE("failed, no cloud DB <%{public}d:0x%{public}x %{public}s<->%{public}s>", meta.tokenId, activeUser,
589 Anonymous::Change(schemaDatabase.name).c_str(), Anonymous::Change(schemaDatabase.alias).c_str());
590 Report(FT_GET_STORE, meta.bundleName, static_cast<int32_t>(Fault::CSF_CONNECT_CLOUD_ASSET_LOADER),
591 "ConnectAssetLoader failed, database=" + schemaDatabase.name);
592 return {};
593 }
594 bindInfos.insert_or_assign(activeUser, GeneralStore::BindInfo{ std::move(cloudDB), std::move(assetLoader) });
595 }
596 return bindInfos;
597 }
598
GetStore(const StoreMetaData & meta,int32_t user,bool mustBind)599 std::pair<int32_t, AutoCache::Store> SyncManager::GetStore(const StoreMetaData &meta, int32_t user, bool mustBind)
600 {
601 if (user != 0 && !Account::GetInstance()->IsVerified(user)) {
602 ZLOGW("user:%{public}d is locked!", user);
603 return { E_USER_UNLOCK, nullptr };
604 }
605 if (CloudServer::GetInstance() == nullptr) {
606 ZLOGD("not support cloud sync");
607 return { E_NOT_SUPPORT, nullptr };
608 }
609 auto [status, store] = AutoCache::GetInstance().GetDBStore(meta, {});
610 if (status == E_SCREEN_LOCKED) {
611 return { E_SCREEN_LOCKED, nullptr };
612 } else if (store == nullptr) {
613 return { E_ERROR, nullptr };
614 }
615 CloudInfo info;
616 info.user = user;
617 std::vector<int32_t> users{};
618 if (info.user == SYSTEM_USER_ID) {
619 AccountDelegate::GetInstance()->QueryForegroundUsers(users);
620 info.user = users.empty() ? SYSTEM_USER_ID : users[0];
621 } else {
622 users.push_back(user);
623 }
624 if (info.user == SYSTEM_USER_ID) {
625 ZLOGE("invalid cloud users, bundleName:%{public}s", meta.bundleName.c_str());
626 return { E_ERROR, nullptr };
627 }
628 if (!store->IsBound(info.user)) {
629 SchemaMeta schemaMeta;
630 std::string schemaKey = info.GetSchemaKey(meta.bundleName, meta.instanceId);
631 if (!MetaDataManager::GetInstance().LoadMeta(schemaKey, schemaMeta, true)) {
632 ZLOGE("failed, no schema bundleName:%{public}s, storeId:%{public}s", meta.bundleName.c_str(),
633 meta.GetStoreAlias().c_str());
634 return { E_ERROR, nullptr };
635 }
636 auto dbMeta = schemaMeta.GetDataBase(meta.storeId);
637 std::map<uint32_t, GeneralStore::BindInfo> bindInfos = GetBindInfos(meta, users, dbMeta);
638 if (mustBind && bindInfos.size() != users.size()) {
639 return { E_ERROR, nullptr };
640 }
641 GeneralStore::CloudConfig config;
642 if (MetaDataManager::GetInstance().LoadMeta(info.GetKey(), info, true)) {
643 config.maxNumber = info.maxNumber;
644 config.maxSize = info.maxSize;
645 }
646 store->Bind(dbMeta, bindInfos, config);
647 }
648 return { E_OK, store };
649 }
650
Report(const ReportParam & reportParam)651 void SyncManager::Report(const ReportParam &reportParam)
652 {
653 auto cloudReport = CloudReport::GetInstance();
654 if (cloudReport == nullptr) {
655 return;
656 }
657 cloudReport->Report(reportParam);
658 }
659
GetPrepareTraceId(const SyncInfo & info,const CloudInfo & cloud)660 SyncManager::TraceIds SyncManager::GetPrepareTraceId(const SyncInfo &info, const CloudInfo &cloud)
661 {
662 TraceIds traceIds;
663 if (!info.prepareTraceId_.empty()) {
664 traceIds.emplace(info.bundleName_, info.prepareTraceId_);
665 return traceIds;
666 }
667 auto cloudReport = CloudReport::GetInstance();
668 if (cloudReport == nullptr) {
669 return traceIds;
670 }
671 if (info.bundleName_.empty()) {
672 for (const auto &it : cloud.apps) {
673 traceIds.emplace(it.first, cloudReport->GetPrepareTraceId(info.user_));
674 }
675 } else {
676 traceIds.emplace(info.bundleName_, cloudReport->GetPrepareTraceId(info.user_));
677 }
678 return traceIds;
679 }
680
NeedGetCloudInfo(CloudInfo & cloud)681 bool SyncManager::NeedGetCloudInfo(CloudInfo &cloud)
682 {
683 return (!MetaDataManager::GetInstance().LoadMeta(cloud.GetKey(), cloud, true) || !cloud.enableCloud) &&
684 NetworkDelegate::GetInstance()->IsNetworkAvailable() && Account::GetInstance()->IsLoginAccount();
685 }
686
GetCloudSyncInfo(const SyncInfo & info,CloudInfo & cloud)687 std::vector<std::tuple<QueryKey, uint64_t>> SyncManager::GetCloudSyncInfo(const SyncInfo &info, CloudInfo &cloud)
688 {
689 std::vector<std::tuple<QueryKey, uint64_t>> cloudSyncInfos;
690 if (NeedGetCloudInfo(cloud)) {
691 ZLOGI("get cloud info from server, user: %{public}d.", cloud.user);
692 auto instance = CloudServer::GetInstance();
693 if (instance == nullptr) {
694 return cloudSyncInfos;
695 }
696 int32_t errCode = SUCCESS;
697 std::tie(errCode, cloud) = instance->GetServerInfo(cloud.user, false);
698 if (!cloud.IsValid()) {
699 ZLOGE("cloud is empty, user: %{public}d", cloud.user);
700 return cloudSyncInfos;
701 }
702 if (!MetaDataManager::GetInstance().SaveMeta(cloud.GetKey(), cloud, true)) {
703 ZLOGW("save cloud info fail, user: %{public}d", cloud.user);
704 }
705 }
706 auto schemaKey = CloudInfo::GetSchemaKey(cloud.user, info.bundleName_);
707 SchemaMeta schemaMeta;
708 if (!MetaDataManager::GetInstance().LoadMeta(schemaKey, schemaMeta, true)) {
709 ZLOGE("load schema fail, bundleName: %{public}s, user %{public}d", info.bundleName_.c_str(), info.user_);
710 return cloudSyncInfos;
711 }
712 auto stores = schemaMeta.GetStores();
713 for (auto &storeId : stores) {
714 QueryKey queryKey{ cloud.user, cloud.id, info.bundleName_, std::move(storeId) };
715 cloudSyncInfos.emplace_back(std::make_tuple(std::move(queryKey), info.syncId_));
716 }
717 return cloudSyncInfos;
718 }
719
GetLastResults(std::map<SyncId,CloudLastSyncInfo> & infos)720 std::pair<int32_t, CloudLastSyncInfo> SyncManager::GetLastResults(std::map<SyncId, CloudLastSyncInfo> &infos)
721 {
722 auto iter = infos.rbegin();
723 if (iter != infos.rend() && iter->second.code != -1) {
724 return { SUCCESS, iter->second };
725 }
726 return { E_ERROR, {} };
727 }
728
NeedSaveSyncInfo(const QueryKey & queryKey)729 bool SyncManager::NeedSaveSyncInfo(const QueryKey &queryKey)
730 {
731 if (queryKey.accountId.empty()) {
732 return false;
733 }
734 return kvApps_.find(queryKey.bundleName) == kvApps_.end();
735 }
736
QueryLastSyncInfo(const std::vector<QueryKey> & queryKeys)737 std::pair<int32_t, std::map<std::string, CloudLastSyncInfo>> SyncManager::QueryLastSyncInfo(
738 const std::vector<QueryKey> &queryKeys)
739 {
740 std::map<std::string, CloudLastSyncInfo> lastSyncInfoMap;
741 for (const auto &queryKey : queryKeys) {
742 std::string storeId = queryKey.storeId;
743 QueryKey key{ queryKey.user, queryKey.accountId, queryKey.bundleName, queryKey.storeId };
744 lastSyncInfos_.ComputeIfPresent(
745 key, [&storeId, &lastSyncInfoMap](auto &key, std::map<SyncId, CloudLastSyncInfo> &vals) {
746 auto [status, syncInfo] = GetLastResults(vals);
747 if (status == SUCCESS) {
748 lastSyncInfoMap.insert(std::make_pair(std::move(storeId), std::move(syncInfo)));
749 }
750 return !vals.empty();
751 });
752 if (lastSyncInfoMap.find(queryKey.storeId) != lastSyncInfoMap.end()) {
753 continue;
754 }
755 auto [status, syncInfo] = GetLastSyncInfoFromMeta(queryKey);
756 if (status == SUCCESS) {
757 lastSyncInfoMap.insert(std::make_pair(std::move(syncInfo.storeId), std::move(syncInfo)));
758 }
759 }
760 return { SUCCESS, lastSyncInfoMap };
761 }
762
UpdateStartSyncInfo(const std::vector<std::tuple<QueryKey,uint64_t>> & cloudSyncInfos)763 void SyncManager::UpdateStartSyncInfo(const std::vector<std::tuple<QueryKey, uint64_t>> &cloudSyncInfos)
764 {
765 int64_t startTime = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
766 for (const auto &[queryKey, syncId] : cloudSyncInfos) {
767 if (!NeedSaveSyncInfo(queryKey)) {
768 continue;
769 }
770 lastSyncInfos_.Compute(queryKey, [id = syncId, startTime](auto &key, std::map<SyncId, CloudLastSyncInfo> &val) {
771 CloudLastSyncInfo syncInfo;
772 syncInfo.id = key.accountId;
773 syncInfo.storeId = key.storeId;
774 syncInfo.startTime = startTime;
775 syncInfo.code = 0;
776 val[id] = std::move(syncInfo);
777 return !val.empty();
778 });
779 }
780 }
781
UpdateFinishSyncInfo(const QueryKey & queryKey,uint64_t syncId,int32_t code)782 void SyncManager::UpdateFinishSyncInfo(const QueryKey &queryKey, uint64_t syncId, int32_t code)
783 {
784 if (!NeedSaveSyncInfo(queryKey)) {
785 return;
786 }
787 lastSyncInfos_.ComputeIfPresent(queryKey, [syncId, code](auto &key,
788 std::map<SyncId, CloudLastSyncInfo> &val) {
789 auto now = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
790 for (auto iter = val.begin(); iter != val.end();) {
791 bool isExpired = ((now - iter->second.startTime) >= EXPIRATION_TIME) && iter->second.code == -1;
792 if ((iter->first != syncId && ((iter->second.code != -1) || isExpired))) {
793 iter = val.erase(iter);
794 } else if (iter->first == syncId) {
795 iter->second.finishTime = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
796 iter->second.code = code;
797 iter->second.syncStatus = SyncStatus::FINISHED;
798 SaveLastSyncInfo(key, std::move(iter->second));
799 iter = val.erase(iter);
800 } else {
801 iter++;
802 }
803 }
804 return true;
805 });
806 }
807
GetCallback(const GenAsync & async,const StoreInfo & storeInfo,int32_t triggerMode,const std::string & prepareTraceId,int32_t user)808 std::function<void(const GenDetails &result)> SyncManager::GetCallback(const GenAsync &async,
809 const StoreInfo &storeInfo, int32_t triggerMode, const std::string &prepareTraceId, int32_t user)
810 {
811 return [this, async, storeInfo, triggerMode, prepareTraceId, user](const GenDetails &result) {
812 if (async != nullptr) {
813 async(result);
814 }
815
816 if (result.empty()) {
817 ZLOGE("result is empty");
818 return;
819 }
820
821 if (result.begin()->second.progress != GenProgress::SYNC_FINISH) {
822 return;
823 }
824
825 int32_t dbCode = (result.begin()->second.dbCode == GenStore::DB_ERR_OFFSET) ? 0 : result.begin()->second.dbCode;
826 RadarReporter::Report({ storeInfo.bundleName.c_str(), CLOUD_SYNC, FINISH_SYNC, storeInfo.syncId, triggerMode,
827 dbCode, result.begin()->second.changeCount },
828 "GetCallback", BizState::END);
829 Report({ user, storeInfo.bundleName, prepareTraceId, SyncStage::END, dbCode });
830 if (dbCode != 0) {
831 Report(FT_CALLBACK, storeInfo.bundleName, static_cast<int32_t>(Fault::CSF_GS_CLOUD_SYNC),
832 "callback failed, dbCode=" + std::to_string(dbCode));
833 }
834 auto id = GetAccountId(storeInfo.user);
835 if (id.empty()) {
836 ZLOGD("account id is empty");
837 return;
838 }
839 int32_t code = result.begin()->second.code;
840 UpdateFinishSyncInfo({ user, id, storeInfo.bundleName, storeInfo.storeName}, storeInfo.syncId, code);
841 };
842 }
843
GetAccountId(int32_t user)844 std::string SyncManager::GetAccountId(int32_t user)
845 {
846 CloudInfo cloudInfo;
847 cloudInfo.user = user;
848 if (!MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetKey(), cloudInfo, true)) {
849 ZLOGE("not exist meta, user:%{public}d.", cloudInfo.user);
850 return "";
851 }
852 return cloudInfo.id;
853 }
854
GetInterval(int32_t code)855 ExecutorPool::Duration SyncManager::GetInterval(int32_t code)
856 {
857 switch (code) {
858 case E_LOCKED_BY_OTHERS:
859 return LOCKED_INTERVAL;
860 case E_BUSY:
861 return BUSY_INTERVAL;
862 default:
863 return RETRY_INTERVAL;
864 }
865 }
866
GetSchemaMeta(const CloudInfo & cloud,const std::string & bundleName)867 std::vector<SchemaMeta> SyncManager::GetSchemaMeta(const CloudInfo &cloud, const std::string &bundleName)
868 {
869 std::vector<SchemaMeta> schemas;
870 auto key = cloud.GetSchemaPrefix(bundleName);
871 MetaDataManager::GetInstance().LoadMeta(key, schemas, true);
872 return schemas;
873 }
874
DoExceptionalCallback(const GenAsync & async,GenDetails & details,const StoreInfo & storeInfo,const std::string & prepareTraceId,int32_t code)875 void SyncManager::DoExceptionalCallback(const GenAsync &async, GenDetails &details, const StoreInfo &storeInfo,
876 const std::string &prepareTraceId, int32_t code)
877 {
878 if (async) {
879 details[SyncInfo::DEFAULT_ID].code = code;
880 async(details);
881 }
882 QueryKey queryKey{ storeInfo.user, GetAccountId(storeInfo.user), storeInfo.bundleName, storeInfo.storeName };
883 UpdateFinishSyncInfo(queryKey, storeInfo.syncId, code);
884 Report({ storeInfo.user, storeInfo.bundleName, prepareTraceId, SyncStage::END, code });
885 }
886
InitDefaultUser(int32_t & user)887 bool SyncManager::InitDefaultUser(int32_t &user)
888 {
889 if (user != 0) {
890 return false;
891 }
892 std::vector<int32_t> users;
893 AccountDelegate::GetInstance()->QueryUsers(users);
894 if (!users.empty()) {
895 user = users[0];
896 }
897 return true;
898 }
899
RetryCallback(const StoreInfo & storeInfo,Retryer retryer,int32_t triggerMode,const std::string & prepareTraceId,int32_t user)900 std::function<void(const DistributedData::GenDetails &result)> SyncManager::RetryCallback(const StoreInfo &storeInfo,
901 Retryer retryer, int32_t triggerMode, const std::string &prepareTraceId, int32_t user)
902 {
903 return [this, retryer, storeInfo, triggerMode, prepareTraceId, user](const GenDetails &details) {
904 if (details.empty()) {
905 ZLOGE("retry, details empty");
906 return;
907 }
908 int32_t code = details.begin()->second.code;
909 int32_t dbCode = details.begin()->second.dbCode;
910 if (details.begin()->second.progress == GenProgress::SYNC_FINISH) {
911 auto user = storeInfo.user;
912 QueryKey queryKey{ user, GetAccountId(user), storeInfo.bundleName, storeInfo.storeName };
913 UpdateFinishSyncInfo(queryKey, storeInfo.syncId, code);
914 if (code == E_OK) {
915 RadarReporter::Report({ storeInfo.bundleName.c_str(), CLOUD_SYNC, FINISH_SYNC, storeInfo.syncId,
916 triggerMode, code, details.begin()->second.changeCount },
917 "RetryCallback", BizState::END);
918 Report({ user, storeInfo.bundleName, prepareTraceId, SyncStage::END,
919 dbCode == GenStore::DB_ERR_OFFSET ? 0 : dbCode });
920 }
921 }
922 retryer(GetInterval(code), code, dbCode, prepareTraceId);
923 };
924 }
925
BatchUpdateFinishState(const std::vector<std::tuple<QueryKey,uint64_t>> & cloudSyncInfos,int32_t code)926 void SyncManager::BatchUpdateFinishState(const std::vector<std::tuple<QueryKey, uint64_t>> &cloudSyncInfos,
927 int32_t code)
928 {
929 for (const auto &[queryKey, syncId] : cloudSyncInfos) {
930 UpdateFinishSyncInfo(queryKey, syncId, code);
931 }
932 }
933
BatchReport(int32_t userId,const TraceIds & traceIds,SyncStage syncStage,int32_t errCode)934 void SyncManager::BatchReport(int32_t userId, const TraceIds &traceIds, SyncStage syncStage, int32_t errCode)
935 {
936 for (const auto &[bundle, id] : traceIds) {
937 Report({ userId, bundle, id, syncStage, errCode });
938 }
939 }
940
GetMetaData(const StoreInfo & storeInfo)941 std::pair<bool, StoreMetaData> SyncManager::GetMetaData(const StoreInfo &storeInfo)
942 {
943 StoreMetaData meta(storeInfo);
944 meta.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
945 if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true)) {
946 meta.user = "0"; // check if it is a public store.
947 StoreMetaDataLocal localMetaData;
948 if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKeyLocal(), localMetaData, true) ||
949 !localMetaData.isPublic || !MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true)) {
950 ZLOGE("failed, no store meta. bundleName:%{public}s, storeId:%{public}s", meta.bundleName.c_str(),
951 meta.GetStoreAlias().c_str());
952 return { false, meta };
953 }
954 }
955 return { true, meta };
956 }
957
OnScreenUnlocked(int32_t user)958 void SyncManager::OnScreenUnlocked(int32_t user)
959 {
960 std::vector<SyncInfo> infos;
961 compensateSyncInfos_.ComputeIfPresent(user,
962 [&infos](auto &userId, const std::map<std::string, std::set<std::string>> &apps) {
963 for (const auto &[bundle, storeIds] : apps) {
964 std::vector<std::string> stores(storeIds.begin(), storeIds.end());
965 infos.push_back(SyncInfo(userId, bundle, stores));
966 }
967 return false;
968 });
969 compensateSyncInfos_.ComputeIfPresent(SYSTEM_USER_ID,
970 [&infos](auto &userId, const std::map<std::string, std::set<std::string>> &apps) {
971 for (const auto &[bundle, storeIds] : apps) {
972 std::vector<std::string> stores(storeIds.begin(), storeIds.end());
973 infos.push_back(SyncInfo(userId, bundle, stores));
974 }
975 return false;
976 });
977 for (auto &info : infos) {
978 info.SetTriggerMode(MODE_UNLOCK);
979 DoCloudSync(info);
980 }
981 }
982
CleanCompensateSync(int32_t userId)983 void SyncManager::CleanCompensateSync(int32_t userId)
984 {
985 compensateSyncInfos_.Erase(userId);
986 }
987
AddCompensateSync(const StoreMetaData & meta)988 void SyncManager::AddCompensateSync(const StoreMetaData &meta)
989 {
990 compensateSyncInfos_.Compute(std::atoi(meta.user.c_str()),
991 [&meta](auto &, std::map<std::string, std::set<std::string>> &apps) {
992 apps[meta.bundleName].insert(meta.storeId);
993 return true;
994 });
995 }
996
GetLastSyncInfoFromMeta(const QueryKey & queryKey)997 std::pair<int32_t, CloudLastSyncInfo> SyncManager::GetLastSyncInfoFromMeta(const QueryKey &queryKey)
998 {
999 CloudLastSyncInfo lastSyncInfo;
1000 if (!MetaDataManager::GetInstance().LoadMeta(CloudLastSyncInfo::GetKey(queryKey.user, queryKey.bundleName,
1001 queryKey.storeId), lastSyncInfo, true)) {
1002 ZLOGE("load last sync info fail, bundleName: %{public}s, user:%{public}d",
1003 queryKey.bundleName.c_str(), queryKey.user);
1004 return { E_ERROR, lastSyncInfo };
1005 }
1006 if (queryKey.accountId != lastSyncInfo.id || (!queryKey.storeId.empty() &&
1007 queryKey.storeId != lastSyncInfo.storeId)) {
1008 return { E_ERROR, lastSyncInfo };
1009 }
1010 return { SUCCESS, std::move(lastSyncInfo) };
1011 }
1012
SaveLastSyncInfo(const QueryKey & queryKey,CloudLastSyncInfo && info)1013 void SyncManager::SaveLastSyncInfo(const QueryKey &queryKey, CloudLastSyncInfo &&info)
1014 {
1015 if (!MetaDataManager::GetInstance().SaveMeta(CloudLastSyncInfo::GetKey(queryKey.user,
1016 queryKey.bundleName, queryKey.storeId), info, true)) {
1017 ZLOGE("save cloud last info fail, bundleName: %{public}s, user:%{public}d",
1018 queryKey.bundleName.c_str(), queryKey.user);
1019 }
1020 }
1021 } // namespace OHOS::CloudData