• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &param)
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