• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "RdbServiceImpl"
16 #include "rdb_service_impl.h"
17 
18 #include "abs_rdb_predicates.h"
19 #include "accesstoken_kit.h"
20 #include "account/account_delegate.h"
21 #include "bootstrap.h"
22 #include "changeevent/remote_change_event.h"
23 #include "checker/checker_manager.h"
24 #include "cloud/change_event.h"
25 #include "cloud/cloud_lock_event.h"
26 #include "cloud/cloud_share_event.h"
27 #include "cloud/make_query_event.h"
28 #include "cloud/schema_meta.h"
29 #include "communicator/device_manager_adapter.h"
30 #include "device_matrix.h"
31 #include "directory/directory_manager.h"
32 #include "dump/dump_manager.h"
33 #include "eventcenter/event_center.h"
34 #include "ipc_skeleton.h"
35 #include "log_print.h"
36 #include "metadata/appid_meta_data.h"
37 #include "metadata/auto_launch_meta_data.h"
38 #include "metadata/capability_meta_data.h"
39 #include "metadata/meta_data_manager.h"
40 #include "metadata/store_debug_info.h"
41 #include "metadata/store_meta_data.h"
42 #include "metadata/store_meta_data_local.h"
43 #include "permit_delegate.h"
44 #include "rdb_general_store.h"
45 #include "rdb_hiview_adapter.h"
46 #include "rdb_notifier_proxy.h"
47 #include "rdb_query.h"
48 #include "rdb_result_set_impl.h"
49 #include "rdb_schema_config.h"
50 #include "rdb_watcher.h"
51 #include "store/general_store.h"
52 #include "tokenid_kit.h"
53 #include "types_export.h"
54 #include "utils/anonymous.h"
55 #include "utils/constant.h"
56 #include "utils/converter.h"
57 #include "xcollie.h"
58 using OHOS::DistributedData::AccountDelegate;
59 using OHOS::DistributedData::Anonymous;
60 using OHOS::DistributedData::CheckerManager;
61 using OHOS::DistributedData::MetaDataManager;
62 using OHOS::DistributedData::StoreMetaData;
63 using OHOS::DistributedData::AccountDelegate;
64 using namespace OHOS::DistributedData;
65 using namespace OHOS::Security::AccessToken;
66 using DistributedDB::RelationalStoreManager;
67 using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter;
68 using RdbSchemaConfig = OHOS::DistributedRdb::RdbSchemaConfig;
69 using DumpManager = OHOS::DistributedData::DumpManager;
70 using system_clock = std::chrono::system_clock;
71 
72 constexpr uint32_t ITERATE_TIMES = 10000;
73 constexpr uint32_t ALLOW_ONLINE_AUTO_SYNC = 8;
74 constexpr int32_t VALID_PARAM_LENGTH = 2;
75 const size_t KEY_COUNT = 2;
76 namespace OHOS::DistributedRdb {
77 __attribute__((used)) RdbServiceImpl::Factory RdbServiceImpl::factory_;
Factory()78 RdbServiceImpl::Factory::Factory()
79 {
80     FeatureSystem::GetInstance().RegisterCreator(RdbServiceImpl::SERVICE_NAME, [this]() {
81         if (product_ == nullptr) {
82             product_ = std::make_shared<RdbServiceImpl>();
83         }
84         return product_;
85     });
86     AutoCache::GetInstance().RegCreator(RDB_DEVICE_COLLABORATION, [](const StoreMetaData& metaData) -> GeneralStore* {
87         auto store = new (std::nothrow) RdbGeneralStore(metaData);
88         if (store != nullptr && !store->IsValid()) {
89             delete store;
90             store = nullptr;
91         }
92         return store;
93     });
94     staticActs_ = std::make_shared<RdbStatic>();
95     FeatureSystem::GetInstance().RegisterStaticActs(RdbServiceImpl::SERVICE_NAME, staticActs_);
96 }
97 
~Factory()98 RdbServiceImpl::Factory::~Factory()
99 {
100 }
101 
RdbServiceImpl()102 RdbServiceImpl::RdbServiceImpl()
103 {
104     ZLOGI("construct");
105     DistributedDB::RelationalStoreManager::SetAutoLaunchRequestCallback(
106         [this](const std::string& identifier, DistributedDB::AutoLaunchParam &param) {
107             return ResolveAutoLaunch(identifier, param);
108         });
109     RegisterEvent();
110 }
111 
ResolveAutoLaunch(const std::string & identifier,DistributedDB::AutoLaunchParam & param)112 int32_t RdbServiceImpl::ResolveAutoLaunch(const std::string &identifier, DistributedDB::AutoLaunchParam &param)
113 {
114     std::string identifierHex = TransferStringToHex(identifier);
115     ZLOGI("%{public}.6s", identifierHex.c_str());
116     std::vector<StoreMetaData> entries;
117     auto localId = DmAdapter::GetInstance().GetLocalDevice().uuid;
118     if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ localId }), entries)) {
119         ZLOGE("get meta failed");
120         return false;
121     }
122     ZLOGI("size=%{public}d", static_cast<int32_t>(entries.size()));
123     for (const auto& entry : entries) {
124         if (entry.storeType != RDB_DEVICE_COLLABORATION) {
125             continue;
126         }
127 
128         auto aIdentifier = DistributedDB::RelationalStoreManager::GetRelationalStoreIdentifier(
129             "", entry.appId, entry.storeId, true);
130         ZLOGD("%{public}s %{public}s %{public}s",
131             entry.user.c_str(), entry.appId.c_str(), Anonymous::Change(entry.storeId).c_str());
132         if (aIdentifier != identifier) {
133             continue;
134         }
135         ZLOGI("find identifier %{public}s", Anonymous::Change(entry.storeId).c_str());
136         param.userId = entry.user;
137         param.appId = entry.appId;
138         param.storeId = entry.storeId;
139         param.path = entry.dataDir;
140         param.option.storeObserver = nullptr;
141         param.option.isEncryptedDb = entry.isEncrypt;
142         if (entry.isEncrypt) {
143             param.option.iterateTimes = ITERATE_TIMES;
144             param.option.cipher = DistributedDB::CipherType::AES_256_GCM;
145         }
146         AutoCache::GetInstance().GetStore(entry, GetWatchers(entry.tokenId, entry.storeId));
147         return true;
148     }
149     ZLOGE("not find identifier");
150     return false;
151 }
152 
OnAppExit(pid_t uid,pid_t pid,uint32_t tokenId,const std::string & bundleName)153 int32_t RdbServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &bundleName)
154 {
155     ZLOGI("client dead, tokenId:%{public}d, pid:%{public}d ", tokenId, pid);
156     bool destroyed = false;
157     syncAgents_.ComputeIfPresent(tokenId, [pid, &destroyed](auto &key, SyncAgents &agents) {
158         auto it = agents.find(pid);
159         if (it != agents.end()) {
160             it->second.SetNotifier(nullptr);
161             agents.erase(it);
162         }
163         if (!agents.empty()) {
164             return true;
165         }
166         destroyed = true;
167         return false;
168     });
169     if (destroyed) {
170         auto stores = AutoCache::GetInstance().GetStoresIfPresent(tokenId);
171         for (auto store : stores) {
172             if (store != nullptr) {
173                 store->UnregisterDetailProgressObserver();
174             }
175         }
176         AutoCache::GetInstance().Enable(tokenId);
177     }
178     heartbeatTaskIds_.Erase(pid);
179     return E_OK;
180 }
181 
OnFeatureExit(pid_t uid,pid_t pid,uint32_t tokenId,const std::string & bundleName)182 int32_t RdbServiceImpl::OnFeatureExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &bundleName)
183 {
184     ZLOGI("rdb exit, tokenId:%{public}d, pid:%{public}d, bundleName:%{public}s.", tokenId, pid, bundleName.c_str());
185     bool destroyed = false;
186     syncAgents_.ComputeIfPresent(tokenId, [pid, &destroyed](auto &key, SyncAgents &agents) {
187         auto it = agents.find(pid);
188         if (it != agents.end()) {
189             it->second.SetNotifier(nullptr);
190             agents.erase(it);
191         }
192         if (!agents.empty()) {
193             return true;
194         }
195         destroyed = true;
196         return false;
197     });
198     if (destroyed) {
199         auto stores = AutoCache::GetInstance().GetStoresIfPresent(tokenId);
200         for (auto store : stores) {
201             if (store != nullptr) {
202                 store->UnregisterDetailProgressObserver();
203             }
204         }
205         AutoCache::GetInstance().Enable(tokenId);
206     }
207     heartbeatTaskIds_.Erase(pid);
208     return E_OK;
209 }
210 
IsValidAccess(const std::string & bundleName,const std::string & storeName)211 bool RdbServiceImpl::IsValidAccess(const std::string& bundleName, const std::string& storeName)
212 {
213     CheckerManager::StoreInfo storeInfo;
214     storeInfo.uid = IPCSkeleton::GetCallingUid();
215     storeInfo.tokenId = IPCSkeleton::GetCallingTokenID();
216     storeInfo.bundleName = bundleName;
217     storeInfo.storeId = RemoveSuffix(storeName);
218 
219     return CheckerManager::GetInstance().IsValid(storeInfo);
220 }
221 
ObtainDistributedTableName(const RdbSyncerParam & param,const std::string & device,const std::string & table)222 std::string RdbServiceImpl::ObtainDistributedTableName(const RdbSyncerParam &param, const std::string &device,
223     const std::string &table)
224 {
225     if (!IsValidAccess(param.bundleName_, "")) {
226         ZLOGE("bundleName:%{public}s. Permission error", param.bundleName_.c_str());
227         return "";
228     }
229     auto tokenId = IPCSkeleton::GetCallingTokenID();
230     std::string appId = " ";
231     if (AccessTokenKit::GetTokenTypeFlag(tokenId) == Security::AccessToken::TOKEN_HAP) {
232         auto uid = IPCSkeleton::GetCallingUid();
233         appId = CheckerManager::GetInstance().GetAppId({ uid, tokenId, param.bundleName_ });
234     }
235     auto uuid = DmAdapter::GetInstance().CalcClientUuid(appId, DmAdapter::GetInstance().ToUUID(device));
236     if (uuid.empty()) {
237         ZLOGE("get uuid failed, bundle:%{public}s, deviceId:%{public}s, table:%{public}s", param.bundleName_.c_str(),
238             Anonymous::Change(device).c_str(), Anonymous::Change(table).c_str());
239         return "";
240     }
241     return DistributedDB::RelationalStoreManager::GetDistributedTableName(uuid, table);
242 }
243 
InitNotifier(const RdbSyncerParam & param,const sptr<IRemoteObject> notifier)244 int32_t RdbServiceImpl::InitNotifier(const RdbSyncerParam &param, const sptr<IRemoteObject> notifier)
245 {
246     XCollie xcollie(__FUNCTION__, XCollie::XCOLLIE_LOG | XCollie::XCOLLIE_RECOVERY);
247     if (!IsValidAccess(param.bundleName_, "")) {
248         ZLOGE("bundleName:%{public}s. Permission error", param.bundleName_.c_str());
249         return RDB_ERROR;
250     }
251     if (notifier == nullptr) {
252         ZLOGE("notifier is null");
253         return RDB_ERROR;
254     }
255 
256     auto notifierProxy = iface_cast<RdbNotifierProxy>(notifier);
257     pid_t pid = IPCSkeleton::GetCallingPid();
258     uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
259     syncAgents_.Compute(tokenId, [bundleName = param.bundleName_, notifierProxy, pid](auto, SyncAgents &agents) {
260         auto [it, success] = agents.try_emplace(pid, SyncAgent(bundleName));
261         if (it == agents.end()) {
262             return true;
263         }
264         it->second.SetNotifier(notifierProxy);
265         return true;
266     });
267     ZLOGI("success tokenId:%{public}x, pid=%{public}d", tokenId, pid);
268     return RDB_OK;
269 }
270 
GetStore(const RdbSyncerParam & param)271 std::shared_ptr<DistributedData::GeneralStore> RdbServiceImpl::GetStore(const RdbSyncerParam &param)
272 {
273     StoreMetaData storeMetaData = GetStoreMetaData(param);
274     MetaDataManager::GetInstance().LoadMeta(storeMetaData.GetKey(), storeMetaData, true);
275     auto watchers = GetWatchers(storeMetaData.tokenId, storeMetaData.storeId);
276     auto store = AutoCache::GetInstance().GetStore(storeMetaData, watchers);
277     if (store == nullptr) {
278         ZLOGE("store null, storeId:%{public}s", storeMetaData.GetStoreAlias().c_str());
279     }
280     return store;
281 }
282 
UpdateMeta(const StoreMetaData & meta,const StoreMetaData & localMeta,AutoCache::Store store)283 void RdbServiceImpl::UpdateMeta(const StoreMetaData &meta, const StoreMetaData &localMeta, AutoCache::Store store)
284 {
285     StoreMetaData syncMeta;
286     bool isCreatedSync = MetaDataManager::GetInstance().LoadMeta(meta.GetKeyWithoutPath(), syncMeta);
287     if (!isCreatedSync || localMeta != syncMeta) {
288         ZLOGI("save sync meta. bundle:%{public}s store:%{public}s type:%{public}d->%{public}d "
289               "encrypt:%{public}d->%{public}d , area:%{public}d->%{public}d",
290             meta.bundleName.c_str(), meta.GetStoreAlias().c_str(), syncMeta.storeType, meta.storeType,
291             syncMeta.isEncrypt, meta.isEncrypt, syncMeta.area, meta.area);
292         MetaDataManager::GetInstance().SaveMeta(meta.GetKeyWithoutPath(), localMeta);
293     }
294     Database dataBase;
295     if (RdbSchemaConfig::GetDistributedSchema(localMeta, dataBase) && !dataBase.name.empty() &&
296         !dataBase.bundleName.empty()) {
297         MetaDataManager::GetInstance().SaveMeta(dataBase.GetKey(), dataBase, true);
298         store->SetConfig({false, GeneralStore::DistributedTableMode::COLLABORATION});
299     }
300 }
301 
SetDistributedTables(const RdbSyncerParam & param,const std::vector<std::string> & tables,const std::vector<Reference> & references,bool isRebuild,int32_t type)302 int32_t RdbServiceImpl::SetDistributedTables(const RdbSyncerParam &param, const std::vector<std::string> &tables,
303     const std::vector<Reference> &references, bool isRebuild, int32_t type)
304 {
305     if (!IsValidParam(param) || !IsValidAccess(param.bundleName_, param.storeName_)) {
306         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
307             Anonymous::Change(param.storeName_).c_str());
308         return RDB_ERROR;
309     }
310     if (type == DistributedTableType::DISTRIBUTED_SEARCH) {
311         DistributedData::SetSearchableEvent::EventInfo eventInfo;
312         eventInfo.isRebuild = isRebuild;
313         return PostSearchEvent(CloudEvent::SET_SEARCH_TRIGGER, param, eventInfo);
314     }
315     auto meta = GetStoreMetaData(param);
316     StoreMetaData localMeta;
317     bool isCreatedLocal = MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), localMeta, true);
318     if (!isCreatedLocal) {
319         ZLOGE("no meta. bundleName:%{public}s, storeName:%{public}s. GetStore failed", param.bundleName_.c_str(),
320               Anonymous::Change(param.storeName_).c_str());
321         return RDB_ERROR;
322     }
323     auto store = GetStore(meta);
324     if (store == nullptr) {
325         ZLOGE("bundle:%{public}s, %{public}s.", param.bundleName_.c_str(), Anonymous::Change(param.storeName_).c_str());
326         return RDB_ERROR;
327     }
328     StoreMetaMapping metaMapping(localMeta);
329     MetaDataManager::GetInstance().LoadMeta(metaMapping.GetKey(), metaMapping, true);
330     if (type == DistributedTableType::DISTRIBUTED_DEVICE) {
331         UpdateMeta(meta, localMeta, store);
332         metaMapping.devicePath = meta.dataDir;
333     } else if (type == DistributedTableType::DISTRIBUTED_CLOUD) {
334         if (localMeta.asyncDownloadAsset != param.asyncDownloadAsset_ || localMeta.enableCloud != param.enableCloud_) {
335             ZLOGI("update meta, bundleName:%{public}s, storeName:%{public}s, asyncDownloadAsset? [%{public}d -> "
336                 "%{public}d],enableCloud? [%{public}d -> %{public}d]", param.bundleName_.c_str(),
337                 Anonymous::Change(param.storeName_).c_str(), localMeta.asyncDownloadAsset, param.asyncDownloadAsset_,
338                 localMeta.enableCloud, param.enableCloud_);
339             localMeta.asyncDownloadAsset = param.asyncDownloadAsset_;
340             localMeta.enableCloud = param.enableCloud_;
341             MetaDataManager::GetInstance().SaveMeta(localMeta.GetKey(), localMeta, true);
342         }
343         metaMapping.cloudPath = meta.dataDir;
344     }
345     metaMapping = localMeta;
346     MetaDataManager::GetInstance().SaveMeta(metaMapping.GetKey(), metaMapping, true);
347     std::vector<DistributedData::Reference> relationships;
348     for (const auto &reference : references) {
349         DistributedData::Reference relationship = { reference.sourceTable, reference.targetTable, reference.refFields };
350         relationships.emplace_back(relationship);
351     }
352     return store->SetDistributedTables(tables, type, relationships);
353 }
354 
OnAsyncComplete(uint32_t tokenId,pid_t pid,uint32_t seqNum,Details && result)355 void RdbServiceImpl::OnAsyncComplete(uint32_t tokenId, pid_t pid, uint32_t seqNum, Details &&result)
356 {
357     ZLOGI("tokenId=%{public}x, pid=%{public}d, seqnum=%{public}u", tokenId, pid, seqNum);
358     sptr<RdbNotifierProxy> notifier = nullptr;
359     syncAgents_.ComputeIfPresent(tokenId, [&notifier, pid](auto, SyncAgents &syncAgents) {
360         auto it = syncAgents.find(pid);
361         if (it != syncAgents.end()) {
362             notifier = it->second.notifier_;
363         }
364         return true;
365     });
366     if (notifier != nullptr) {
367         notifier->OnComplete(seqNum, std::move(result));
368     }
369 }
370 
TransferStringToHex(const std::string & origStr)371 std::string RdbServiceImpl::TransferStringToHex(const std::string &origStr)
372 {
373     if (origStr.empty()) {
374         return "";
375     }
376     const char *hex = "0123456789abcdef";
377     std::string tmp;
378     for (auto item : origStr) {
379         auto currentByte = static_cast<uint8_t>(item);
380         tmp.push_back(hex[currentByte >> 4]); // high 4 bit to one hex.
381         tmp.push_back(hex[currentByte & 0x0F]); // low 4 bit to one hex.
382     }
383     return tmp;
384 }
385 
GetWatchers(uint32_t tokenId,const std::string & storeName)386 AutoCache::Watchers RdbServiceImpl::GetWatchers(uint32_t tokenId, const std::string &storeName)
387 {
388     AutoCache::Watchers watchers;
389     syncAgents_.ComputeIfPresent(tokenId, [&watchers](auto, SyncAgents &syncAgents) {
390         std::for_each(syncAgents.begin(), syncAgents.end(), [&watchers](const auto &item) {
391             if (item.second.watcher_ != nullptr) {
392                 watchers.insert(item.second.watcher_);
393             }
394         });
395         return true;
396     });
397     return watchers;
398 }
399 
GetCallbacks(uint32_t tokenId,const std::string & storeName)400 RdbServiceImpl::DetailAsync RdbServiceImpl::GetCallbacks(uint32_t tokenId, const std::string &storeName)
401 {
402     std::list<sptr<RdbNotifierProxy>> notifiers;
403     syncAgents_.ComputeIfPresent(tokenId, [&storeName, &notifiers](auto, SyncAgents &syncAgents) {
404         std::for_each(syncAgents.begin(), syncAgents.end(), [&storeName, &notifiers](const auto &item) {
405             if (item.second.callBackStores_.count(storeName) != 0) {
406                 notifiers.push_back(item.second.notifier_);
407             }
408         });
409         return true;
410     });
411     if (notifiers.empty()) {
412         return nullptr;
413     }
414     return [notifiers, storeName](const GenDetails &details) {
415         for (const auto &notifier : notifiers) {
416             if (notifier != nullptr) {
417                 notifier->OnComplete(storeName, HandleGenDetails(details));
418             }
419         }
420     };
421 }
422 
RemoteQuery(const RdbSyncerParam & param,const std::string & device,const std::string & sql,const std::vector<std::string> & selectionArgs)423 std::pair<int32_t, std::shared_ptr<RdbServiceImpl::ResultSet>> RdbServiceImpl::RemoteQuery(const RdbSyncerParam& param,
424     const std::string& device, const std::string& sql, const std::vector<std::string>& selectionArgs)
425 {
426     if (!IsValidParam(param) || !IsValidAccess(param.bundleName_, param.storeName_)) {
427         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
428             Anonymous::Change(param.storeName_).c_str());
429         return { RDB_ERROR, nullptr };
430     }
431     StoreMetaData meta = GetStoreMetaData(param);
432     auto store = GetStore(meta);
433     if (store == nullptr) {
434         ZLOGE("bundleName:%{public}s, storeName:%{public}s. GetStore failed", param.bundleName_.c_str(),
435             Anonymous::Change(param.storeName_).c_str());
436         return { RDB_ERROR, nullptr };
437     }
438     std::vector<std::string> devices = { DmAdapter::GetInstance().ToUUID(device) };
439     if (IsNeedMetaSync(meta, devices) && !MetaDataManager::GetInstance().Sync(
440         devices, [](auto &results) {}, true)) {
441         ZLOGW("bundleName:%{public}s, storeName:%{public}s. meta sync failed", param.bundleName_.c_str(),
442             Anonymous::Change(param.storeName_).c_str());
443     }
444     RdbQuery rdbQuery;
445     rdbQuery.MakeRemoteQuery(DmAdapter::GetInstance().ToUUID(device), sql, ValueProxy::Convert(selectionArgs));
446     auto [errCode, cursor] = store->Query("", rdbQuery);
447     if (errCode != GeneralError::E_OK) {
448         return { RDB_ERROR, nullptr };
449     }
450     return { RDB_OK, std::make_shared<RdbResultSetImpl>(cursor) };
451 }
452 
Sync(const RdbSyncerParam & param,const Option & option,const PredicatesMemo & predicates,const AsyncDetail & async)453 int32_t RdbServiceImpl::Sync(const RdbSyncerParam &param, const Option &option, const PredicatesMemo &predicates,
454                              const AsyncDetail &async)
455 {
456     if (!IsValidParam(param) || !IsValidAccess(param.bundleName_, param.storeName_)) {
457         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
458             Anonymous::Change(param.storeName_).c_str());
459         return RDB_ERROR;
460     }
461     if (option.mode < DistributedData::GeneralStore::CLOUD_END &&
462         option.mode >= DistributedData::GeneralStore::CLOUD_BEGIN) {
463         DoCloudSync(param, option, predicates, async);
464         return RDB_OK;
465     }
466     return DoSync(param, option, predicates, async);
467 }
468 
DoSync(const RdbSyncerParam & param,const RdbService::Option & option,const PredicatesMemo & predicates,const AsyncDetail & async)469 int RdbServiceImpl::DoSync(const RdbSyncerParam &param, const RdbService::Option &option,
470     const PredicatesMemo &predicates, const AsyncDetail &async)
471 {
472     StoreMetaData meta = GetStoreMetaData(param);
473     auto store = GetStore(meta);
474     if (store == nullptr) {
475         return RDB_ERROR;
476     }
477     RdbQuery rdbQuery;
478     rdbQuery.MakeQuery(predicates);
479     auto devices = rdbQuery.GetDevices().empty() ? DmAdapter::ToUUID(DmAdapter::GetInstance().GetRemoteDevices())
480                                                  : DmAdapter::ToUUID(rdbQuery.GetDevices());
481     auto pid = IPCSkeleton::GetCallingPid();
482     SyncParam syncParam = { option.mode, 0, option.isCompensation };
483     auto tokenId = IPCSkeleton::GetCallingTokenID();
484     ZLOGD("seqNum=%{public}u", option.seqNum);
485     auto complete = [this, rdbQuery, store, pid, syncParam, tokenId, seq = option.seqNum](
486                         const auto &results) mutable {
487         auto ret = ProcessResult(results);
488         store->Sync(
489             ret.first, rdbQuery,
490             [this, tokenId, seq, pid](const GenDetails &result) mutable {
491                 OnAsyncComplete(tokenId, pid, seq, HandleGenDetails(result));
492             },
493             syncParam);
494     };
495     if (IsNeedMetaSync(meta, devices)) {
496         auto result = MetaDataManager::GetInstance().Sync(devices, complete);
497         return result ? GeneralError::E_OK : GeneralError::E_ERROR;
498     }
499     return store->Sync(
500         devices, rdbQuery,
501         [this, tokenId, pid, seqNum = option.seqNum](const GenDetails &result) mutable {
502             OnAsyncComplete(tokenId, pid, seqNum, HandleGenDetails(result));
503         },
504         syncParam).first;
505 }
506 
IsNeedMetaSync(const StoreMetaData & meta,const std::vector<std::string> & uuids)507 bool RdbServiceImpl::IsNeedMetaSync(const StoreMetaData &meta, const std::vector<std::string> &uuids)
508 {
509     bool isAfterMeta = false;
510     for (const auto &uuid : uuids) {
511         auto metaData = meta;
512         metaData.deviceId = uuid;
513         CapMetaData capMeta;
514         auto capKey = CapMetaRow::GetKeyFor(uuid);
515         if (!MetaDataManager::GetInstance().LoadMeta(std::string(capKey.begin(), capKey.end()), capMeta) ||
516             !MetaDataManager::GetInstance().LoadMeta(metaData.GetKeyWithoutPath(), metaData)) {
517             isAfterMeta = true;
518             break;
519         }
520         auto [exist, mask] = DeviceMatrix::GetInstance().GetRemoteMask(uuid);
521         if ((mask & DeviceMatrix::META_STORE_MASK) == DeviceMatrix::META_STORE_MASK) {
522             isAfterMeta = true;
523             break;
524         }
525         auto [existLocal, localMask] = DeviceMatrix::GetInstance().GetMask(uuid);
526         if ((localMask & DeviceMatrix::META_STORE_MASK) == DeviceMatrix::META_STORE_MASK) {
527             isAfterMeta = true;
528             break;
529         }
530     }
531     return isAfterMeta;
532 }
533 
ProcessResult(const std::map<std::string,int32_t> & results)534 RdbServiceImpl::SyncResult RdbServiceImpl::ProcessResult(const std::map<std::string, int32_t> &results)
535 {
536     std::map<std::string, DBStatus> dbResults;
537     std::vector<std::string> devices;
538     for (const auto &[uuid, status] : results) {
539         dbResults.insert_or_assign(uuid, static_cast<DBStatus>(status));
540         if (static_cast<DBStatus>(status) != DBStatus::OK) {
541             continue;
542         }
543         DeviceMatrix::GetInstance().OnExchanged(uuid, DeviceMatrix::META_STORE_MASK);
544         devices.emplace_back(uuid);
545     }
546     ZLOGD("meta sync finish, total size:%{public}zu, success size:%{public}zu", dbResults.size(), devices.size());
547     return { devices, dbResults };
548 }
549 
DoCompensateSync(const BindEvent & event)550 void RdbServiceImpl::DoCompensateSync(const BindEvent& event)
551 {
552     auto bindInfo = event.GetBindInfo();
553     StoreInfo storeInfo;
554     storeInfo.bundleName = bindInfo.bundleName;
555     storeInfo.tokenId = bindInfo.tokenId;
556     storeInfo.user = bindInfo.user;
557     storeInfo.storeName = bindInfo.storeName;
558     OHOS::NativeRdb::AbsRdbPredicates predicates(bindInfo.tableName);
559     for (auto& [key, value] : bindInfo.primaryKey) {
560         predicates.In(key, std::vector<NativeRdb::ValueObject>({ ValueProxy::Convert(std::move(value)) }));
561     }
562     auto memo = predicates.GetDistributedPredicates();
563     std::shared_ptr<RdbQuery> query = nullptr;
564     if (!memo.tables_.empty()) {
565         query = std::make_shared<RdbQuery>();
566         query->MakeCloudQuery(memo);
567     }
568     auto mixMode = event.GetEventId() == BindEvent::COMPENSATE_SYNC
569                        ? GeneralStore::MixMode(TIME_FIRST, GeneralStore::AUTO_SYNC_MODE)
570                        : GeneralStore::MixMode(CLOUD_FIRST, GeneralStore::AUTO_SYNC_MODE);
571     auto info = ChangeEvent::EventInfo(mixMode, 0, false, query, nullptr);
572     auto evt = std::make_unique<ChangeEvent>(std::move(storeInfo), std::move(info));
573     EventCenter::GetInstance().PostEvent(std::move(evt));
574 }
575 
DoCloudSync(const RdbSyncerParam & param,const RdbService::Option & option,const PredicatesMemo & predicates,const AsyncDetail & async)576 void RdbServiceImpl::DoCloudSync(const RdbSyncerParam &param, const RdbService::Option &option,
577     const PredicatesMemo &predicates, const AsyncDetail &async)
578 {
579     StoreInfo storeInfo;
580     storeInfo.bundleName = param.bundleName_;
581     storeInfo.tokenId = IPCSkeleton::GetCallingTokenID();
582     storeInfo.user = AccountDelegate::GetInstance()->GetUserByToken(storeInfo.tokenId);
583     storeInfo.storeName = RemoveSuffix(param.storeName_);
584     std::shared_ptr<RdbQuery> query = nullptr;
585     if (!predicates.tables_.empty()) {
586         query = std::make_shared<RdbQuery>();
587         query->MakeCloudQuery(predicates);
588     }
589     auto pid = IPCSkeleton::GetCallingPid();
590     GenAsync asyncCallback = [this, tokenId = storeInfo.tokenId, seqNum = option.seqNum, pid](
591                                  const GenDetails &result) mutable {
592         OnAsyncComplete(tokenId, pid, seqNum, HandleGenDetails(result));
593     };
594     GenAsync syncCallback = [async, &param](const GenDetails &details) {
595         ZLOGD("Cloud Sync complete, bundleName:%{public}s, storeName:%{public}s", param.bundleName_.c_str(),
596             Anonymous::Change(param.storeName_).c_str());
597         if (async != nullptr) {
598             async(HandleGenDetails(details));
599         }
600     };
601     auto highMode = (!predicates.tables_.empty() && option.mode == DistributedData::GeneralStore::CLOUD_CLOUD_FIRST)
602                     ? GeneralStore::ASSETS_SYNC_MODE
603                     : (option.isAutoSync ? GeneralStore::AUTO_SYNC_MODE : GeneralStore::MANUAL_SYNC_MODE);
604     auto mixMode = static_cast<int32_t>(GeneralStore::MixMode(option.mode, highMode));
605     SyncParam syncParam = { mixMode, (option.isAsync ? 0 : static_cast<int32_t>(WAIT_TIME)), option.isCompensation };
606     syncParam.asyncDownloadAsset = param.asyncDownloadAsset_;
607     auto info = ChangeEvent::EventInfo(syncParam, option.isAutoSync, query,
608         option.isAutoSync ? nullptr
609         : option.isAsync  ? asyncCallback
610                           : syncCallback);
611     auto evt = std::make_unique<ChangeEvent>(std::move(storeInfo), std::move(info));
612     EventCenter::GetInstance().PostEvent(std::move(evt));
613 }
614 
Subscribe(const RdbSyncerParam & param,const SubscribeOption & option,std::shared_ptr<RdbStoreObserver> observer)615 int32_t RdbServiceImpl::Subscribe(const RdbSyncerParam &param, const SubscribeOption &option,
616     std::shared_ptr<RdbStoreObserver> observer)
617 {
618     if (option.mode < 0 || option.mode >= SUBSCRIBE_MODE_MAX) {
619         ZLOGE("mode:%{public}d error", option.mode);
620         return RDB_ERROR;
621     }
622     pid_t pid = IPCSkeleton::GetCallingPid();
623     auto tokenId = IPCSkeleton::GetCallingTokenID();
624     bool isCreate = false;
625     syncAgents_.Compute(tokenId, [pid, &param, &isCreate](auto &key, SyncAgents &agents) {
626         auto [it, _] = agents.try_emplace(pid, param.bundleName_);
627         if (it == agents.end()) {
628             return !agents.empty();
629         }
630         if (it->second.watcher_ == nullptr) {
631             isCreate = true;
632             it->second.SetWatcher(std::make_shared<RdbWatcher>());
633         }
634         it->second.count_++;
635         return true;
636     });
637     if (isCreate) {
638         AutoCache::GetInstance().SetObserver(tokenId, GetWatchers(tokenId, param.storeName_),
639             GetPath(param), RemoveSuffix(param.storeName_));
640     }
641     return RDB_OK;
642 }
643 
UnSubscribe(const RdbSyncerParam & param,const SubscribeOption & option,std::shared_ptr<RdbStoreObserver> observer)644 int32_t RdbServiceImpl::UnSubscribe(const RdbSyncerParam &param, const SubscribeOption &option,
645     std::shared_ptr<RdbStoreObserver> observer)
646 {
647     if (option.mode < 0 || option.mode >= SUBSCRIBE_MODE_MAX) {
648         ZLOGE("mode:%{public}d error", option.mode);
649         return RDB_ERROR;
650     }
651     bool destroyed = false;
652     auto tokenId = IPCSkeleton::GetCallingTokenID();
653     auto pid = IPCSkeleton::GetCallingPid();
654     syncAgents_.ComputeIfPresent(tokenId, [pid, &destroyed](auto, SyncAgents &agents) {
655         auto it = agents.find(pid);
656         if (it == agents.end()) {
657             return !agents.empty();
658         }
659         it->second.count_--;
660         if (it->second.count_ <= 0) {
661             destroyed = true;
662             it->second.SetWatcher(nullptr);
663         }
664         return true;
665     });
666     if (destroyed) {
667         AutoCache::GetInstance().SetObserver(tokenId, GetWatchers(tokenId, param.storeName_),
668             GetPath(param), RemoveSuffix(param.storeName_));
669     }
670     return RDB_OK;
671 }
672 
RegisterAutoSyncCallback(const RdbSyncerParam & param,std::shared_ptr<DetailProgressObserver> observer)673 int32_t RdbServiceImpl::RegisterAutoSyncCallback(const RdbSyncerParam& param,
674     std::shared_ptr<DetailProgressObserver> observer)
675 {
676     pid_t pid = IPCSkeleton::GetCallingPid();
677     auto tokenId = IPCSkeleton::GetCallingTokenID();
678     auto storeName = RemoveSuffix(param.storeName_);
679     syncAgents_.Compute(tokenId, [pid, &param, &storeName](auto, SyncAgents &agents) {
680         auto [it, success] = agents.try_emplace(pid, param.bundleName_);
681         if (it == agents.end()) {
682             return !agents.empty();
683         }
684         if (success) {
685             it->second.callBackStores_.insert(std::make_pair(storeName, 0));
686         }
687         it->second.callBackStores_[storeName]++;
688         return true;
689     });
690     return RDB_OK;
691 }
692 
UnregisterAutoSyncCallback(const RdbSyncerParam & param,std::shared_ptr<DetailProgressObserver> observer)693 int32_t RdbServiceImpl::UnregisterAutoSyncCallback(const RdbSyncerParam& param,
694     std::shared_ptr<DetailProgressObserver> observer)
695 {
696     auto tokenId = IPCSkeleton::GetCallingTokenID();
697     auto pid = IPCSkeleton::GetCallingPid();
698     auto storeName = RemoveSuffix(param.storeName_);
699     syncAgents_.ComputeIfPresent(tokenId, [pid, &storeName](auto, SyncAgents &agents) {
700         auto agent = agents.find(pid);
701         if (agent == agents.end()) {
702             return !agents.empty();
703         }
704         auto it = agent->second.callBackStores_.find(storeName);
705         if (it == agent->second.callBackStores_.end()) {
706             return !agents.empty();
707         }
708         it->second--;
709         if (it->second <= 0) {
710             agent->second.callBackStores_.erase(it);
711         }
712         return !agents.empty();
713     });
714     return RDB_OK;
715 }
716 
Delete(const RdbSyncerParam & param)717 int32_t RdbServiceImpl::Delete(const RdbSyncerParam &param)
718 {
719     XCollie xcollie(__FUNCTION__, XCollie::XCOLLIE_LOG | XCollie::XCOLLIE_RECOVERY);
720     if (!IsValidAccess(param.bundleName_, param.storeName_)) {
721         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
722             Anonymous::Change(param.storeName_).c_str());
723         return RDB_ERROR;
724     }
725     auto tokenId = IPCSkeleton::GetCallingTokenID();
726     auto storeMeta = GetStoreMetaData(param);
727     StoreMetaMapping storeMetaMapping(storeMeta);
728     MetaDataManager::GetInstance().LoadMeta(storeMetaMapping.GetKey(), storeMetaMapping, true);
729     if (!MetaDataManager::GetInstance().LoadMeta(storeMeta.GetKey(), storeMeta, true)) {
730         storeMeta.dataDir = storeMetaMapping.dataDir;
731     }
732     AutoCache::GetInstance().CloseStore(tokenId, storeMeta.dataDir, RemoveSuffix(param.storeName_));
733     MetaDataManager::GetInstance().DelMeta(storeMeta.GetKeyWithoutPath());
734     MetaDataManager::GetInstance().DelMeta(storeMeta.GetKey(), true);
735     MetaDataManager::GetInstance().DelMeta(storeMeta.GetKeyLocal(), true);
736     MetaDataManager::GetInstance().DelMeta(storeMeta.GetSecretKey(), true);
737     MetaDataManager::GetInstance().DelMeta(storeMeta.GetStrategyKey());
738     MetaDataManager::GetInstance().DelMeta(storeMeta.GetBackupSecretKey(), true);
739     MetaDataManager::GetInstance().DelMeta(storeMeta.GetAutoLaunchKey(), true);
740     MetaDataManager::GetInstance().DelMeta(storeMeta.GetDebugInfoKey(), true);
741     MetaDataManager::GetInstance().DelMeta(storeMeta.GetDfxInfoKey(), true);
742     MetaDataManager::GetInstance().DelMeta(storeMeta.GetCloneSecretKey(), true);
743     std::vector<StoreMetaData> metaList;
744     if (MetaDataManager::GetInstance().LoadMeta(storeMeta.GetKeyWithoutPath(), metaList, true) && !metaList.empty()) {
745         if (storeMetaMapping.cloudPath == storeMetaMapping.dataDir) {
746             storeMetaMapping.cloudPath = "";
747         }
748         if (storeMetaMapping.searchPath == storeMetaMapping.dataDir) {
749             storeMetaMapping.searchPath = "";
750         }
751         if (storeMetaMapping.devicePath == storeMetaMapping.dataDir) {
752             storeMetaMapping.devicePath = "";
753         }
754         storeMetaMapping = metaList[0];
755         MetaDataManager::GetInstance().SaveMeta(storeMetaMapping.GetKey(), storeMetaMapping, true);
756     } else {
757         MetaDataManager::GetInstance().DelMeta(storeMetaMapping.GetKey(), true);
758     }
759     return RDB_OK;
760 }
761 
QuerySharingResource(const RdbSyncerParam & param,const PredicatesMemo & predicates,const std::vector<std::string> & columns)762 std::pair<int32_t, std::shared_ptr<RdbService::ResultSet>> RdbServiceImpl::QuerySharingResource(
763     const RdbSyncerParam& param, const PredicatesMemo& predicates, const std::vector<std::string>& columns)
764 {
765     if (!IsValidAccess(param.bundleName_, param.storeName_) ||
766         !TokenIdKit::IsSystemAppByFullTokenID(IPCSkeleton::GetCallingFullTokenID())) {
767         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
768             Anonymous::Change(param.storeName_).c_str());
769         return { RDB_ERROR, {} };
770     }
771     if (predicates.tables_.empty()) {
772         ZLOGE("tables is empty, bundleName:%{public}s, storeName:%{public}s", param.bundleName_.c_str(),
773             Anonymous::Change(param.storeName_).c_str());
774         return { RDB_ERROR, {} };
775     }
776     auto rdbQuery = std::make_shared<RdbQuery>();
777     rdbQuery->MakeQuery(predicates);
778     rdbQuery->SetColumns(columns);
779     StoreInfo storeInfo;
780     storeInfo.bundleName = param.bundleName_;
781     storeInfo.tokenId = IPCSkeleton::GetCallingTokenID();
782     storeInfo.user = AccountDelegate::GetInstance()->GetUserByToken(storeInfo.tokenId);
783     storeInfo.storeName = RemoveSuffix(param.storeName_);
784     auto [status, cursor] = AllocResource(storeInfo, rdbQuery);
785     if (cursor == nullptr) {
786         ZLOGE("cursor is null, bundleName:%{public}s, storeName:%{public}s", param.bundleName_.c_str(),
787             Anonymous::Change(param.storeName_).c_str());
788         return { RDB_ERROR, {} };
789     }
790     return { RDB_OK, std::make_shared<RdbResultSetImpl>(cursor) };
791 }
792 
AllocResource(StoreInfo & storeInfo,std::shared_ptr<RdbQuery> rdbQuery)793 std::pair<int32_t, std::shared_ptr<Cursor>> RdbServiceImpl::AllocResource(StoreInfo& storeInfo,
794     std::shared_ptr<RdbQuery> rdbQuery)
795 {
796     std::pair<int32_t, std::shared_ptr<Cursor>> result;
797     CloudShareEvent::Callback asyncCallback = [&result](int32_t status, std::shared_ptr<Cursor> cursor) {
798         result.first = status;
799         result.second = cursor;
800     };
801     auto evt = std::make_unique<CloudShareEvent>(std::move(storeInfo), rdbQuery, asyncCallback);
802     EventCenter::GetInstance().PostEvent(std::move(evt));
803     return result;
804 }
805 
IsValidPath(const std::string & param)806 bool RdbServiceImpl::IsValidPath(const std::string &param)
807 {
808     if ((param.find("/") != std::string::npos) || (param.find("\\") != std::string::npos) || (param == "..")) {
809         return false;
810     }
811     return true;
812 }
813 
IsValidCustomDir(const std::string & customDir,int32_t upLimit)814 bool RdbServiceImpl::IsValidCustomDir(const std::string &customDir, int32_t upLimit)
815 {
816     if (customDir.empty()) {
817         return true;
818     }
819     if (customDir[0] == '/') {
820         return false;
821     }
822     std::vector<std::string> components = Constant::Split(customDir, "/");
823     int32_t up = 0;
824     for (const auto &comp : components) {
825         if (comp.empty() || comp == ".") {
826             continue;
827         }
828         if (comp != "..") {
829             up--;
830             continue;
831         }
832         if (++up > upLimit) {
833             return false;
834         }
835     }
836     return true;
837 }
838 
IsValidParam(const RdbSyncerParam & param)839 bool RdbServiceImpl::IsValidParam(const RdbSyncerParam &param)
840 {
841     if (param.storeName_.find("/") != std::string::npos) {
842         ZLOGE("storeName is Invalid, storeName is %{public}s.", Anonymous::Change(param.storeName_).c_str());
843         return false;
844     }
845     if (!IsValidPath(param.bundleName_)) {
846         ZLOGE("bundleName is Invalid, bundleName is %{public}s.", param.bundleName_.c_str());
847         return false;
848     }
849     if (!IsValidPath(param.user_)) {
850         ZLOGE("user is Invalid, user is %{public}s.", param.user_.c_str());
851         return false;
852     }
853     if (!IsValidPath(param.hapName_)) {
854         ZLOGE("hapName is Invalid, hapName is %{public}s.", param.hapName_.c_str());
855         return false;
856     }
857     int32_t upLimit = param.hapName_.empty() ? 1 : VALID_PARAM_LENGTH;
858     if (!IsValidCustomDir(param.customDir_, upLimit)) {
859         ZLOGE("customDir is Invalid, customDir is %{public}s.", Anonymous::Change(param.customDir_).c_str());
860         return false;
861     }
862     return true;
863 }
864 
BeforeOpen(RdbSyncerParam & param)865 int32_t RdbServiceImpl::BeforeOpen(RdbSyncerParam &param)
866 {
867     XCollie xcollie(__FUNCTION__, XCollie::XCOLLIE_LOG | XCollie::XCOLLIE_RECOVERY);
868     if (!IsValidParam(param) || !IsValidAccess(param.bundleName_, param.storeName_)) {
869         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
870             Anonymous::Change(param.storeName_).c_str());
871         return RDB_ERROR;
872     }
873     auto [exist, meta] = LoadStoreMetaData(param);
874     if (!exist) {
875         ZLOGW("bundleName:%{public}s, storeName:%{public}s. no meta", param.bundleName_.c_str(),
876             Anonymous::Change(param.storeName_).c_str());
877         return RDB_NO_META;
878     }
879     SetReturnParam(meta, param);
880     return RDB_OK;
881 }
882 
SetReturnParam(const StoreMetaData & metadata,RdbSyncerParam & param)883 void RdbServiceImpl::SetReturnParam(const StoreMetaData &metadata, RdbSyncerParam &param)
884 {
885     param.bundleName_ = metadata.bundleName;
886     param.type_ = metadata.storeType;
887     param.level_ = metadata.securityLevel;
888     param.area_ = metadata.area;
889     param.hapName_ = metadata.hapName;
890     param.customDir_ = metadata.customDir;
891     param.isEncrypt_ = metadata.isEncrypt;
892     param.isAutoClean_ = !metadata.isManualClean;
893     param.isSearchable_ = metadata.isSearchable;
894     param.haMode_ = metadata.haMode;
895 }
896 
SaveLaunchInfo(StoreMetaData & meta)897 void RdbServiceImpl::SaveLaunchInfo(StoreMetaData &meta)
898 {
899     RemoteChangeEvent::DataInfo info;
900     info.bundleName = meta.bundleName;
901     info.deviceId = meta.deviceId;
902     info.userId = meta.user;
903     if (executors_ != nullptr) {
904         executors_->Schedule(ExecutorPool::INVALID_DELAY, [dataInfo = std::move(info)]() mutable {
905             auto evt = std::make_unique<RemoteChangeEvent>(RemoteChangeEvent::RDB_META_SAVE, std::move(dataInfo));
906             EventCenter::GetInstance().PostEvent(std::move(evt));
907         });
908     }
909 }
910 
SaveSecretKeyMeta(const StoreMetaData & metaData,const std::vector<uint8_t> & password)911 void RdbServiceImpl::SaveSecretKeyMeta(const StoreMetaData &metaData, const std::vector<uint8_t> &password)
912 {
913     CryptoManager::CryptoParams encryptParams = { .area = metaData.area, .userId = metaData.user };
914     auto encryptKey = CryptoManager::GetInstance().Encrypt(password, encryptParams);
915     if (!encryptKey.empty() && !encryptParams.nonce.empty()) {
916         SecretKeyMetaData secretKey;
917         secretKey.storeType = metaData.storeType;
918         secretKey.area = metaData.area;
919         secretKey.sKey = encryptKey;
920         secretKey.nonce = encryptParams.nonce;
921         auto time = system_clock::to_time_t(system_clock::now());
922         secretKey.time = { reinterpret_cast<uint8_t *>(&time), reinterpret_cast<uint8_t *>(&time) + sizeof(time) };
923         MetaDataManager::GetInstance().SaveMeta(metaData.GetSecretKey(), secretKey, true);
924     }
925     SecretKeyMetaData cloneKey;
926     auto metaKey = metaData.GetCloneSecretKey();
927     // update clone secret key with area
928     if (MetaDataManager::GetInstance().LoadMeta(metaKey, cloneKey, true) && !cloneKey.sKey.empty() &&
929         (cloneKey.nonce.empty() || cloneKey.area < 0)) {
930         CryptoManager::CryptoParams decryptParams = { .area = cloneKey.area, .userId = metaData.user,
931             .nonce = cloneKey.nonce };
932         auto clonePassword = CryptoManager::GetInstance().Decrypt(cloneKey.sKey, decryptParams);
933         if (!clonePassword.empty()) {
934             CryptoManager::GetInstance().UpdateSecretMeta(clonePassword, metaData, metaKey, cloneKey);
935         }
936         clonePassword.assign(clonePassword.size(), 0);
937     }
938 }
939 
AfterOpen(const RdbSyncerParam & param)940 int32_t RdbServiceImpl::AfterOpen(const RdbSyncerParam &param)
941 {
942     XCollie xcollie(__FUNCTION__, XCollie::XCOLLIE_LOG | XCollie::XCOLLIE_RECOVERY);
943     if (!IsValidParam(param) || !IsValidAccess(param.bundleName_, param.storeName_)) {
944         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
945             Anonymous::Change(param.storeName_).c_str());
946         return RDB_ERROR;
947     }
948     auto meta = GetStoreMetaData(param);
949     StoreMetaData old;
950     auto isCreated = MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), old, true);
951     meta.enableCloud = isCreated ? old.enableCloud : meta.enableCloud;
952     if (!isCreated || meta != old) {
953         Upgrade(param, old);
954         ZLOGI("meta bundle:%{public}s store:%{public}s type:%{public}d->%{public}d encrypt:%{public}d->%{public}d "
955             "area:%{public}d->%{public}d", meta.bundleName.c_str(), meta.GetStoreAlias().c_str(), old.storeType,
956             meta.storeType, old.isEncrypt, meta.isEncrypt, old.area, meta.area);
957         meta.isNeedUpdateDeviceId = isCreated && !TryUpdateDeviceId(param, old, meta);
958         MetaDataManager::GetInstance().SaveMeta(meta.GetKey(), meta, true);
959         AutoLaunchMetaData launchData;
960         if (!MetaDataManager::GetInstance().LoadMeta(meta.GetAutoLaunchKey(), launchData, true)) {
961             SaveLaunchInfo(meta);
962         }
963     }
964 
965     StoreMetaMapping metaMapping(meta);
966     MetaDataManager::GetInstance().LoadMeta(metaMapping.GetKey(), metaMapping, true);
967     if (meta.isSearchable) {
968         metaMapping.searchPath = meta.dataDir;
969     }
970     metaMapping = meta;
971     MetaDataManager::GetInstance().SaveMeta(metaMapping.GetKey(), metaMapping, true);
972 
973     SaveDebugInfo(meta, param);
974     SavePromiseInfo(meta, param);
975     SaveDfxInfo(meta, param);
976 
977     if (!SaveAppIDMeta(meta, old)) {
978         return RDB_ERROR;
979     }
980 
981     if (param.isEncrypt_ && !param.password_.empty()) {
982         SaveSecretKeyMeta(meta, param.password_);
983     }
984     GetSchema(param);
985     return RDB_OK;
986 }
987 
SaveAppIDMeta(const StoreMetaData & meta,const StoreMetaData & old)988 bool RdbServiceImpl::SaveAppIDMeta(const StoreMetaData &meta, const StoreMetaData &old)
989 {
990     AppIDMetaData appIdMeta;
991     appIdMeta.bundleName = meta.bundleName;
992     appIdMeta.appId = meta.appId;
993     if (!MetaDataManager::GetInstance().SaveMeta(appIdMeta.GetKey(), appIdMeta, true)) {
994         ZLOGE("meta bundle:%{public}s store:%{public}s type:%{public}d->%{public}d encrypt:%{public}d->%{public}d "
995             "area:%{public}d->%{public}d", meta.bundleName.c_str(), meta.GetStoreAlias().c_str(), old.storeType,
996             meta.storeType, old.isEncrypt, meta.isEncrypt, old.area, meta.area);
997         return false;
998     }
999     return true;
1000 }
1001 
ReportStatistic(const RdbSyncerParam & param,const RdbStatEvent & statEvent)1002 int32_t RdbServiceImpl::ReportStatistic(const RdbSyncerParam& param, const RdbStatEvent &statEvent)
1003 {
1004     if (!IsValidAccess(param.bundleName_, param.storeName_)) {
1005         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
1006             Anonymous::Change(param.storeName_).c_str());
1007         return RDB_ERROR;
1008     }
1009     RdbHiViewAdapter::GetInstance().ReportStatistic(statEvent);
1010     return RDB_OK;
1011 }
1012 
GetSchema(const RdbSyncerParam & param)1013 void RdbServiceImpl::GetSchema(const RdbSyncerParam &param)
1014 {
1015     if (executors_ != nullptr) {
1016         StoreInfo storeInfo;
1017         storeInfo.tokenId = IPCSkeleton::GetCallingTokenID();
1018         storeInfo.bundleName = param.bundleName_;
1019         storeInfo.storeName = RemoveSuffix(param.storeName_);
1020         auto [instanceId,  user]= GetInstIndexAndUser(storeInfo.tokenId, param.bundleName_);
1021         storeInfo.instanceId = instanceId;
1022         storeInfo.user = user;
1023         storeInfo.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
1024         auto meta = GetStoreMetaData(param);
1025         storeInfo.path = meta.dataDir;
1026         executors_->Execute([storeInfo]() {
1027             auto event = std::make_unique<CloudEvent>(CloudEvent::GET_SCHEMA, std::move(storeInfo));
1028             EventCenter::GetInstance().PostEvent(move(event));
1029             return;
1030         });
1031     }
1032 }
1033 
LoadStoreMetaData(const RdbSyncerParam & param)1034 std::pair<bool, StoreMetaData> RdbServiceImpl::LoadStoreMetaData(const RdbSyncerParam &param)
1035 {
1036     StoreMetaData metaData;
1037     metaData.uid = IPCSkeleton::GetCallingUid();
1038     metaData.tokenId = IPCSkeleton::GetCallingTokenID();
1039     auto [instanceId, user] = GetInstIndexAndUser(metaData.tokenId, param.bundleName_);
1040     metaData.instanceId = instanceId;
1041     metaData.bundleName = param.bundleName_;
1042     metaData.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
1043     metaData.storeId = RemoveSuffix(param.storeName_);
1044     if (AccessTokenKit::GetTokenTypeFlag(metaData.tokenId) != TOKEN_HAP && param.subUser_ != 0) {
1045         metaData.user = std::to_string(param.subUser_);
1046     } else {
1047         metaData.user = std::to_string(user);
1048     }
1049     metaData.storeType = param.type_;
1050     metaData.securityLevel = param.level_;
1051     metaData.area = param.area_;
1052     metaData.appId = CheckerManager::GetInstance().GetAppId(Converter::ConvertToStoreInfo(metaData));
1053     metaData.appType = "harmony";
1054     metaData.hapName = param.hapName_;
1055     metaData.customDir = param.customDir_;
1056     metaData.dataDir = DirectoryManager::GetInstance().GetStorePath(metaData) + "/" + param.storeName_;
1057     auto exist = MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData, true);
1058     return {exist, metaData};
1059 }
1060 
GetStoreMetaData(const RdbSyncerParam & param)1061 StoreMetaData RdbServiceImpl::GetStoreMetaData(const RdbSyncerParam &param)
1062 {
1063     StoreMetaData metaData;
1064     metaData.uid = IPCSkeleton::GetCallingUid();
1065     metaData.tokenId = IPCSkeleton::GetCallingTokenID();
1066     auto [instanceId, user] = GetInstIndexAndUser(metaData.tokenId, param.bundleName_);
1067     metaData.instanceId = instanceId;
1068     metaData.bundleName = param.bundleName_;
1069     metaData.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
1070     metaData.storeId = RemoveSuffix(param.storeName_);
1071     if (AccessTokenKit::GetTokenTypeFlag(metaData.tokenId) != TOKEN_HAP && param.subUser_ != 0) {
1072         metaData.user = std::to_string(param.subUser_);
1073     } else {
1074         metaData.user = std::to_string(user);
1075     }
1076     metaData.storeType = param.type_;
1077     metaData.securityLevel = param.level_;
1078     metaData.area = param.area_;
1079     metaData.appId = CheckerManager::GetInstance().GetAppId(Converter::ConvertToStoreInfo(metaData));
1080     metaData.appType = "harmony";
1081     metaData.hapName = param.hapName_;
1082     metaData.customDir = param.customDir_;
1083     metaData.dataDir = DirectoryManager::GetInstance().GetStorePath(metaData) + "/" + param.storeName_;
1084     metaData.account = AccountDelegate::GetInstance()->GetCurrentAccountId();
1085     metaData.isEncrypt = param.isEncrypt_;
1086     metaData.isManualClean = !param.isAutoClean_;
1087     metaData.isSearchable = param.isSearchable_;
1088     metaData.haMode = param.haMode_;
1089     metaData.asyncDownloadAsset = param.asyncDownloadAsset_;
1090     return metaData;
1091 }
1092 
Upgrade(const RdbSyncerParam & param,const StoreMetaData & old)1093 int32_t RdbServiceImpl::Upgrade(const RdbSyncerParam &param, const StoreMetaData &old)
1094 {
1095     if (old.storeType == RDB_DEVICE_COLLABORATION && old.version < StoreMetaData::UUID_CHANGED_TAG) {
1096         auto store = GetStore(param);
1097         if (store == nullptr) {
1098             ZLOGE("store is null, bundleName:%{public}s storeName:%{public}s", param.bundleName_.c_str(),
1099                 Anonymous::Change(param.storeName_).c_str());
1100             return RDB_ERROR;
1101         }
1102         return store->Clean({}, GeneralStore::CleanMode::NEARBY_DATA, "") == GeneralError::E_OK ? RDB_OK : RDB_ERROR;
1103     }
1104     return RDB_OK;
1105 }
1106 
HandleGenDetails(const GenDetails & details)1107 Details RdbServiceImpl::HandleGenDetails(const GenDetails &details)
1108 {
1109     Details dbDetails;
1110     for (const auto& [id, detail] : details) {
1111         auto &dbDetail = dbDetails[id];
1112         dbDetail.progress = detail.progress;
1113         dbDetail.code = detail.code;
1114         for (auto &[name, table] : detail.details) {
1115             auto &dbTable = dbDetail.details[name];
1116             Constant::Copy(&dbTable, &table);
1117         }
1118     }
1119     return dbDetails;
1120 }
1121 
RemoveSuffix(const std::string & name)1122 std::string RdbServiceImpl::RemoveSuffix(const std::string& name)
1123 {
1124     std::string suffix(".db");
1125     auto pos = name.rfind(suffix);
1126     if (pos == std::string::npos || pos < name.length() - suffix.length()) {
1127         return name;
1128     }
1129     return std::string(name, 0, pos);
1130 }
1131 
GetInstIndexAndUser(uint32_t tokenId,const std::string & bundleName)1132 std::pair<int32_t, int32_t> RdbServiceImpl::GetInstIndexAndUser(uint32_t tokenId, const std::string &bundleName)
1133 {
1134     if (AccessTokenKit::GetTokenTypeFlag(tokenId) != TOKEN_HAP) {
1135         return { 0, 0 };
1136     }
1137 
1138     HapTokenInfo tokenInfo;
1139     tokenInfo.instIndex = -1;
1140     int errCode = AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo);
1141     if (errCode != RET_SUCCESS) {
1142         ZLOGE("GetHapTokenInfo error:%{public}d, tokenId:0x%{public}x appId:%{public}s", errCode, tokenId,
1143             bundleName.c_str());
1144         return { -1, -1 };
1145     }
1146     return { tokenInfo.instIndex, tokenInfo.userID };
1147 }
1148 
OnBind(const BindInfo & bindInfo)1149 int32_t RdbServiceImpl::OnBind(const BindInfo &bindInfo)
1150 {
1151     executors_ = bindInfo.executors;
1152     RdbHiViewAdapter::GetInstance().SetThreadPool(executors_);
1153     return 0;
1154 }
1155 
GetStoreMetaData(const Database & dataBase)1156 StoreMetaData RdbServiceImpl::GetStoreMetaData(const Database &dataBase)
1157 {
1158     StoreMetaMapping storeMetaMapping;
1159     storeMetaMapping.storeId = dataBase.name;
1160     storeMetaMapping.bundleName = dataBase.bundleName;
1161     storeMetaMapping.user = dataBase.user;
1162     storeMetaMapping.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
1163     auto tokenId = IPCSkeleton::GetCallingTokenID();
1164     storeMetaMapping.tokenId = tokenId;
1165     auto [instanceId, user] = GetInstIndexAndUser(storeMetaMapping.tokenId, storeMetaMapping.bundleName);
1166     storeMetaMapping.instanceId = instanceId;
1167     MetaDataManager::GetInstance().LoadMeta(storeMetaMapping.GetKey(), storeMetaMapping, true);
1168     StoreMetaData storeMetaData = storeMetaMapping;
1169     if (storeMetaMapping.dataDir != storeMetaMapping.devicePath) {
1170         MetaDataManager::GetInstance().LoadMeta(storeMetaMapping.GetDeviceStoreMetaKey(), storeMetaData, true);
1171     }
1172     return storeMetaData;
1173 }
1174 
GetStore(const StoreMetaData & storeMetaData)1175 std::shared_ptr<DistributedData::GeneralStore> RdbServiceImpl::GetStore(const StoreMetaData &storeMetaData)
1176 {
1177     auto watchers = GetWatchers(storeMetaData.tokenId, storeMetaData.storeId);
1178     auto store = AutoCache::GetInstance().GetStore(storeMetaData, watchers);
1179     return store;
1180 }
1181 
GetReuseDevice(const std::vector<std::string> & devices,const StoreMetaData & metaData)1182 std::vector<std::string> RdbServiceImpl::GetReuseDevice(const std::vector<std::string> &devices,
1183     const StoreMetaData &metaData)
1184 {
1185     std::vector<std::string> onDevices;
1186     auto instance = AppDistributedKv::ProcessCommunicatorImpl::GetInstance();
1187     AppDistributedKv::ExtraDataInfo extraInfo = { .userId = metaData.user, .bundleName = metaData.bundleName,
1188         .storeId = metaData.storeId, .tokenId = metaData.tokenId };
1189     for (auto &device : devices) {
1190         AppDistributedKv::DeviceId deviceId = { .deviceId = device };
1191         if (instance->ReuseConnect(deviceId, extraInfo) == Status::SUCCESS) {
1192             onDevices.push_back(device);
1193         }
1194     }
1195     return onDevices;
1196 }
1197 
DoAutoSync(const std::vector<std::string> & devices,const Database & dataBase,std::vector<std::string> tables)1198 int RdbServiceImpl::DoAutoSync(
1199     const std::vector<std::string> &devices, const Database &dataBase, std::vector<std::string> tables)
1200 {
1201     StoreMetaData storeMetaData = GetStoreMetaData(dataBase);
1202     auto store = GetStore(storeMetaData);
1203     if (store == nullptr) {
1204         ZLOGE("autosync store null, storeId:%{public}s", storeMetaData.GetStoreAlias().c_str());
1205         return RDB_ERROR;
1206     }
1207     if (executors_ == nullptr) {
1208         ZLOGE("autosync executors_ null, storeId:%{public}s", storeMetaData.GetStoreAlias().c_str());
1209         return RDB_ERROR;
1210     }
1211     SyncParam syncParam = { 0, 0 };
1212     DetailAsync async;
1213     for (auto &table : tables) {
1214         executors_->Execute([this, table, store, syncParam, async, devices, storeMetaData]() {
1215             RdbQuery rdbQuery;
1216             rdbQuery.MakeQuery(table);
1217             std::vector<std::string> onDevices = GetReuseDevice(devices, storeMetaData);
1218             if (onDevices.empty()) {
1219                 ZLOGE("autosync ondevices null, storeId:%{public}s", storeMetaData.GetStoreAlias().c_str());
1220                 return;
1221             }
1222             auto complete = [this, rdbQuery, store, syncParam, async](
1223                                 const auto &results) mutable {
1224                 auto ret = ProcessResult(results);
1225                 store->Sync(ret.first, rdbQuery, async, syncParam);
1226             };
1227             if (IsNeedMetaSync(storeMetaData, onDevices)) {
1228                 MetaDataManager::GetInstance().Sync(onDevices, complete);
1229                 return;
1230             }
1231             (void)store->Sync(onDevices, rdbQuery, async, syncParam).first;
1232             return;
1233         });
1234     }
1235     return RDB_OK;
1236 }
1237 
DoOnlineSync(const std::vector<std::string> & devices,const Database & dataBase)1238 int RdbServiceImpl::DoOnlineSync(const std::vector<std::string> &devices, const Database &dataBase)
1239 {
1240     std::vector<std::string> tableNames;
1241     for (auto &table : dataBase.tables) {
1242         if (!table.deviceSyncFields.empty()) {
1243             tableNames.push_back(table.name);
1244         }
1245     }
1246     return DoAutoSync(devices, dataBase, tableNames);
1247 }
1248 
OnReady(const std::string & device)1249 int32_t RdbServiceImpl::OnReady(const std::string &device)
1250 {
1251     int index = ALLOW_ONLINE_AUTO_SYNC;
1252     Database dataBase;
1253     std::string prefix = dataBase.GetPrefix({});
1254     std::vector<Database> dataBases;
1255     if (!MetaDataManager::GetInstance().LoadMeta(prefix, dataBases, true)) {
1256         return 0;
1257     }
1258     for (auto dataBase : dataBases) {
1259         if ((dataBase.autoSyncType == AutoSyncType::SYNC_ON_READY ||
1260                 dataBase.autoSyncType == AutoSyncType::SYNC_ON_CHANGE_READY) &&
1261             index > 0) {
1262             std::vector<std::string> devices = {device};
1263             if (DoOnlineSync(devices, dataBase) != RDB_OK) {
1264                 ZLOGE("store online sync fail, storeId:%{public}s", Anonymous::Change(dataBase.name).c_str());
1265             }
1266             index--;
1267         }
1268     }
1269     return 0;
1270 }
1271 
SetNotifier(sptr<RdbNotifierProxy> notifier)1272 void RdbServiceImpl::SyncAgent::SetNotifier(sptr<RdbNotifierProxy> notifier)
1273 {
1274     notifier_ = notifier;
1275     if (watcher_ != nullptr) {
1276         watcher_->SetNotifier(notifier);
1277     }
1278 }
1279 
SetWatcher(std::shared_ptr<RdbWatcher> watcher)1280 void RdbServiceImpl::SyncAgent::SetWatcher(std::shared_ptr<RdbWatcher> watcher)
1281 {
1282     if (watcher_ != watcher) {
1283         watcher_ = watcher;
1284         if (watcher_ != nullptr) {
1285             watcher_->SetNotifier(notifier_);
1286         }
1287     }
1288 }
1289 
SyncAgent(const std::string & bundleName)1290 RdbServiceImpl::SyncAgent::SyncAgent(const std::string &bundleName) : bundleName_(bundleName)
1291 {
1292     notifier_ = nullptr;
1293     watcher_ = nullptr;
1294     count_ = 0;
1295     callBackStores_.clear();
1296 }
1297 
CloseStore(const std::string & bundleName,int32_t user,int32_t index,int32_t tokenId) const1298 int32_t RdbServiceImpl::RdbStatic::CloseStore(const std::string &bundleName, int32_t user, int32_t index,
1299     int32_t tokenId) const
1300 {
1301     if (tokenId != RdbServiceImpl::RdbStatic::INVALID_TOKENID) {
1302         AutoCache::GetInstance().CloseStore(tokenId);
1303         return E_OK;
1304     }
1305     std::string prefix = StoreMetaData::GetPrefix(
1306         { DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid, std::to_string(user), "default", bundleName });
1307     std::vector<StoreMetaData> storeMetaData;
1308     if (!MetaDataManager::GetInstance().LoadMeta(prefix, storeMetaData, true)) {
1309         ZLOGE("load meta failed! bundleName:%{public}s, user:%{public}d, index:%{public}d",
1310             bundleName.c_str(), user, index);
1311         return E_ERROR;
1312     }
1313     for (const auto &meta : storeMetaData) {
1314         if (meta.storeType < StoreMetaData::STORE_RELATIONAL_BEGIN ||
1315             meta.storeType > StoreMetaData::STORE_RELATIONAL_END) {
1316             continue;
1317         }
1318         if (meta.instanceId == index && !meta.appId.empty() && !meta.storeId.empty()) {
1319             AutoCache::GetInstance().CloseStore(meta.tokenId);
1320             break;
1321         }
1322     }
1323     return E_OK;
1324 }
1325 
OnAppUninstall(const std::string & bundleName,int32_t user,int32_t index)1326 int32_t RdbServiceImpl::RdbStatic::OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index)
1327 {
1328     std::string prefix = Database::GetPrefix({std::to_string(user), "default", bundleName});
1329     std::vector<Database> dataBase;
1330     if (MetaDataManager::GetInstance().LoadMeta(prefix, dataBase, true)) {
1331         for (const auto &dataBase : dataBase) {
1332             MetaDataManager::GetInstance().DelMeta(dataBase.GetKey(), true);
1333         }
1334     }
1335     return CloseStore(bundleName, user, index);
1336 }
1337 
OnAppUpdate(const std::string & bundleName,int32_t user,int32_t index)1338 int32_t RdbServiceImpl::RdbStatic::OnAppUpdate(const std::string &bundleName, int32_t user, int32_t index)
1339 {
1340     std::string prefix = Database::GetPrefix({std::to_string(user), "default", bundleName});
1341     std::vector<Database> dataBase;
1342     if (MetaDataManager::GetInstance().LoadMeta(prefix, dataBase, true)) {
1343         for (const auto &database : dataBase) {
1344             MetaDataManager::GetInstance().DelMeta(database.GetKey(), true);
1345             ZLOGD("del metadata store is: %{public}s; user is: %{public}s; bundleName is: %{public}s",
1346                 Anonymous::Change(database.name).c_str(), database.user.c_str(), database.bundleName.c_str());
1347             StoreMetaData meta;
1348             meta.user = database.user;
1349             meta.deviceId = database.deviceId;
1350             meta.storeId = database.name;
1351             meta.bundleName = bundleName;
1352             Database base;
1353             if (RdbSchemaConfig::GetDistributedSchema(meta, base) && !base.name.empty() && !base.bundleName.empty()) {
1354                 MetaDataManager::GetInstance().SaveMeta(base.GetKey(), base, true);
1355                 ZLOGD("save metadata store is: %{public}s; user is: %{public}s; bundleName is: %{public}s",
1356                     Anonymous::Change(base.name).c_str(), base.user.c_str(), base.bundleName.c_str());
1357             }
1358         }
1359     }
1360     return CloseStore(bundleName, user, index);
1361 }
1362 
OnClearAppStorage(const std::string & bundleName,int32_t user,int32_t index,int32_t tokenId)1363 int32_t RdbServiceImpl::RdbStatic::OnClearAppStorage(const std::string &bundleName, int32_t user, int32_t index,
1364     int32_t tokenId)
1365 {
1366     return CloseStore(bundleName, user, index, tokenId);
1367 }
1368 
RegisterRdbServiceInfo()1369 void RdbServiceImpl::RegisterRdbServiceInfo()
1370 {
1371     DumpManager::Config serviceInfoConfig;
1372     serviceInfoConfig.fullCmd = "--feature-info";
1373     serviceInfoConfig.abbrCmd = "-f";
1374     serviceInfoConfig.dumpName = "FEATURE_INFO";
1375     serviceInfoConfig.dumpCaption = { "| Display all the service statistics" };
1376     DumpManager::GetInstance().AddConfig("FEATURE_INFO", serviceInfoConfig);
1377 }
1378 
RegisterHandler()1379 void RdbServiceImpl::RegisterHandler()
1380 {
1381     Handler handler =
1382         std::bind(&RdbServiceImpl::DumpRdbServiceInfo, this, std::placeholders::_1, std::placeholders::_2);
1383     DumpManager::GetInstance().AddHandler("FEATURE_INFO", uintptr_t(this), handler);
1384 }
DumpRdbServiceInfo(int fd,std::map<std::string,std::vector<std::string>> & params)1385 void RdbServiceImpl::DumpRdbServiceInfo(int fd, std::map<std::string, std::vector<std::string>> &params)
1386 {
1387     (void)params;
1388     std::string info;
1389     dprintf(fd, "-------------------------------------RdbServiceInfo------------------------------\n%s\n",
1390         info.c_str());
1391 }
OnInitialize()1392 int32_t RdbServiceImpl::OnInitialize()
1393 {
1394     RegisterRdbServiceInfo();
1395     RegisterHandler();
1396     return RDB_OK;
1397 }
1398 
~RdbServiceImpl()1399 RdbServiceImpl::~RdbServiceImpl()
1400 {
1401     DumpManager::GetInstance().RemoveHandler("FEATURE_INFO", uintptr_t(this));
1402 }
1403 
DoDataChangeSync(const StoreInfo & storeInfo,const RdbChangedData & rdbChangedData)1404 int RdbServiceImpl::DoDataChangeSync(const StoreInfo &storeInfo, const RdbChangedData &rdbChangedData)
1405 {
1406     std::vector<std::string> tableNames;
1407     Database dataBase;
1408     dataBase.bundleName = storeInfo.bundleName;
1409     dataBase.name = storeInfo.storeName;
1410     dataBase.user = std::to_string(storeInfo.user);
1411     dataBase.deviceId = storeInfo.deviceId;
1412     for (const auto &[key, value] : rdbChangedData.tableData) {
1413         if (value.isP2pSyncDataChange) {
1414             tableNames.push_back(key);
1415         }
1416     }
1417     if (MetaDataManager::GetInstance().LoadMeta(dataBase.GetKey(), dataBase, true)) {
1418         std::vector<std::string> devices = DmAdapter::ToUUID(DmAdapter::GetInstance().GetRemoteDevices());
1419         if ((dataBase.autoSyncType == AutoSyncType::SYNC_ON_CHANGE ||
1420                 dataBase.autoSyncType == AutoSyncType::SYNC_ON_CHANGE_READY) &&
1421             !devices.empty()) {
1422             return DoAutoSync(devices, dataBase, tableNames);
1423         }
1424     }
1425     return RDB_OK;
1426 }
1427 
NotifyDataChange(const RdbSyncerParam & param,const RdbChangedData & rdbChangedData,const RdbNotifyConfig & rdbNotifyConfig)1428 int32_t RdbServiceImpl::NotifyDataChange(
1429     const RdbSyncerParam &param, const RdbChangedData &rdbChangedData, const RdbNotifyConfig &rdbNotifyConfig)
1430 {
1431     XCollie xcollie(__FUNCTION__, XCollie::XCOLLIE_LOG | XCollie::XCOLLIE_RECOVERY);
1432     if (!IsValidParam(param) || !IsValidAccess(param.bundleName_, param.storeName_)) {
1433         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
1434             Anonymous::Change(param.storeName_).c_str());
1435         return RDB_ERROR;
1436     }
1437     StoreInfo storeInfo;
1438     storeInfo.tokenId = IPCSkeleton::GetCallingTokenID();
1439     storeInfo.bundleName = param.bundleName_;
1440     storeInfo.storeName = RemoveSuffix(param.storeName_);
1441     storeInfo.path = GetPath(param);
1442     auto [instanceId, user] = GetInstIndexAndUser(storeInfo.tokenId, param.bundleName_);
1443     storeInfo.instanceId = instanceId;
1444     storeInfo.user = user;
1445     storeInfo.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
1446     DataChangeEvent::EventInfo eventInfo;
1447     eventInfo.isFull = rdbNotifyConfig.isFull_;
1448     if (DoDataChangeSync(storeInfo, rdbChangedData) != RDB_OK) {
1449         ZLOGE("store datachange sync fail, storeId:%{public}s", Anonymous::Change(storeInfo.storeName).c_str());
1450     }
1451     for (const auto &[key, value] : rdbChangedData.tableData) {
1452         if (value.isTrackedDataChange) {
1453             DataChangeEvent::TableChangeProperties tableChangeProperties = {value.isTrackedDataChange};
1454             eventInfo.tableProperties.insert_or_assign(key, std::move(tableChangeProperties));
1455         }
1456     }
1457     if (IsPostImmediately(IPCSkeleton::GetCallingPid(), rdbNotifyConfig, storeInfo, eventInfo, storeInfo.path)) {
1458         auto evt = std::make_unique<DataChangeEvent>(std::move(storeInfo), std::move(eventInfo));
1459         EventCenter::GetInstance().PostEvent(std::move(evt));
1460     }
1461     return RDB_OK;
1462 }
1463 
IsPostImmediately(const int32_t callingPid,const RdbNotifyConfig & rdbNotifyConfig,StoreInfo & storeInfo,DataChangeEvent::EventInfo & eventInfo,const std::string & path)1464 bool RdbServiceImpl::IsPostImmediately(const int32_t callingPid, const RdbNotifyConfig &rdbNotifyConfig,
1465     StoreInfo &storeInfo, DataChangeEvent::EventInfo &eventInfo, const std::string &path)
1466 {
1467     bool postImmediately = false;
1468     heartbeatTaskIds_.Compute(callingPid, [this, &postImmediately, &rdbNotifyConfig, &storeInfo, &eventInfo,
1469         &path](const int32_t &key, std::map<std::string, ExecutorPool::TaskId> &tasks) {
1470         auto iter = tasks.find(path);
1471         ExecutorPool::TaskId taskId = ExecutorPool::INVALID_TASK_ID;
1472         if (iter != tasks.end()) {
1473             taskId = iter->second;
1474         }
1475         if (rdbNotifyConfig.delay_ == 0) {
1476             if (taskId != ExecutorPool::INVALID_TASK_ID && executors_ != nullptr) {
1477                 executors_->Remove(taskId);
1478             }
1479             postImmediately = true;
1480             tasks.erase(path);
1481             return !tasks.empty();
1482         }
1483 
1484         if (executors_ != nullptr) {
1485             auto task = [storeInfoInner = storeInfo, eventInfoInner = eventInfo]() {
1486                 auto evt = std::make_unique<DataChangeEvent>(std::move(storeInfoInner), std::move(eventInfoInner));
1487                 EventCenter::GetInstance().PostEvent(std::move(evt));
1488             };
1489             if (taskId == ExecutorPool::INVALID_TASK_ID) {
1490                 taskId = executors_->Schedule(std::chrono::milliseconds(rdbNotifyConfig.delay_), task);
1491             } else {
1492                 taskId = executors_->Reset(taskId, std::chrono::milliseconds(rdbNotifyConfig.delay_));
1493             }
1494         }
1495         tasks.insert_or_assign(path, taskId);
1496         return true;
1497     });
1498     return postImmediately;
1499 }
1500 
SetSearchable(const RdbSyncerParam & param,bool isSearchable)1501 int32_t RdbServiceImpl::SetSearchable(const RdbSyncerParam& param, bool isSearchable)
1502 {
1503     XCollie xcollie(__FUNCTION__, XCollie::XCOLLIE_LOG | XCollie::XCOLLIE_RECOVERY);
1504     if (!IsValidAccess(param.bundleName_, param.storeName_)) {
1505         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
1506             Anonymous::Change(param.storeName_).c_str());
1507         return RDB_ERROR;
1508     }
1509     SetSearchableEvent::EventInfo eventInfo;
1510     eventInfo.isSearchable = isSearchable;
1511     return PostSearchEvent(CloudEvent::SET_SEARCHABLE, param, eventInfo);
1512 }
1513 
PostSearchEvent(int32_t evtId,const RdbSyncerParam & param,SetSearchableEvent::EventInfo & eventInfo)1514 int32_t RdbServiceImpl::PostSearchEvent(int32_t evtId, const RdbSyncerParam& param,
1515     SetSearchableEvent::EventInfo &eventInfo)
1516 {
1517     StoreInfo storeInfo;
1518     storeInfo.tokenId = IPCSkeleton::GetCallingTokenID();
1519     storeInfo.bundleName = param.bundleName_;
1520     storeInfo.storeName = RemoveSuffix(param.storeName_);
1521     auto [instanceId,  user]= GetInstIndexAndUser(storeInfo.tokenId, param.bundleName_);
1522     storeInfo.instanceId = instanceId;
1523     storeInfo.user = user;
1524     storeInfo.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
1525     storeInfo.path = GetPath(param);
1526 
1527     auto evt = std::make_unique<SetSearchableEvent>(std::move(storeInfo), std::move(eventInfo), evtId);
1528     EventCenter::GetInstance().PostEvent(std::move(evt));
1529     return RDB_OK;
1530 }
1531 
Disable(const RdbSyncerParam & param)1532 int32_t RdbServiceImpl::Disable(const RdbSyncerParam &param)
1533 {
1534     auto tokenId = IPCSkeleton::GetCallingTokenID();
1535     auto storeId = RemoveSuffix(param.storeName_);
1536     AutoCache::GetInstance().Disable(tokenId, GetPath(param), storeId);
1537     return RDB_OK;
1538 }
1539 
Enable(const RdbSyncerParam & param)1540 int32_t RdbServiceImpl::Enable(const RdbSyncerParam &param)
1541 {
1542     auto tokenId = IPCSkeleton::GetCallingTokenID();
1543     auto storeId = RemoveSuffix(param.storeName_);
1544     AutoCache::GetInstance().Enable(tokenId, GetPath(param), storeId);
1545     return RDB_OK;
1546 }
1547 
LoadSecretKey(const StoreMetaData & metaData,CryptoManager::SecretKeyType secretKeyType)1548 std::vector<uint8_t> RdbServiceImpl::LoadSecretKey(const StoreMetaData &metaData,
1549     CryptoManager::SecretKeyType secretKeyType)
1550 {
1551     SecretKeyMetaData secretKey;
1552     std::string metaKey;
1553     if (secretKeyType == CryptoManager::SecretKeyType::LOCAL_SECRET_KEY) {
1554         metaKey = metaData.GetSecretKey();
1555     } else if (secretKeyType == CryptoManager::SecretKeyType::CLONE_SECRET_KEY) {
1556         metaKey = metaData.GetCloneSecretKey();
1557     }
1558     if (!MetaDataManager::GetInstance().LoadMeta(metaKey, secretKey, true) || secretKey.sKey.empty()) {
1559         return {};
1560     }
1561     CryptoManager::CryptoParams decryptParams = { .area = secretKey.area, .userId = metaData.user,
1562         .nonce = secretKey.nonce };
1563     auto password = CryptoManager::GetInstance().Decrypt(secretKey.sKey, decryptParams);
1564     if (password.empty()) {
1565         return {};
1566     }
1567     // update secret key of area or nonce
1568     CryptoManager::GetInstance().UpdateSecretMeta(password, metaData, metaKey, secretKey);
1569     return password;
1570 }
1571 
GetPassword(const RdbSyncerParam & param,std::vector<std::vector<uint8_t>> & password)1572 int32_t RdbServiceImpl::GetPassword(const RdbSyncerParam &param, std::vector<std::vector<uint8_t>> &password)
1573 {
1574     if (!IsValidAccess(param.bundleName_, param.storeName_)) {
1575         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
1576             Anonymous::Change(param.storeName_).c_str());
1577         return RDB_ERROR;
1578     }
1579     password.reserve(KEY_COUNT);
1580     auto meta = GetStoreMetaData(param);
1581     auto key = LoadSecretKey(meta, CryptoManager::SecretKeyType::LOCAL_SECRET_KEY);
1582     if (!key.empty()) {
1583         password.emplace_back(key);
1584     }
1585     auto cloneKey = LoadSecretKey(meta, CryptoManager::SecretKeyType::CLONE_SECRET_KEY);
1586     if (!cloneKey.empty()) {
1587         password.emplace_back(cloneKey);
1588     }
1589     return password.size() > 0 ? RDB_OK : RDB_ERROR;
1590 }
1591 
GetStoreInfo(const RdbSyncerParam & param)1592 StoreInfo RdbServiceImpl::GetStoreInfo(const RdbSyncerParam &param)
1593 {
1594     StoreInfo storeInfo;
1595     storeInfo.bundleName = param.bundleName_;
1596     storeInfo.tokenId = IPCSkeleton::GetCallingTokenID();
1597     storeInfo.user = AccountDelegate::GetInstance()->GetUserByToken(storeInfo.tokenId);
1598     storeInfo.storeName = RemoveSuffix(param.storeName_);
1599     auto meta = GetStoreMetaData(param);
1600     storeInfo.path = meta.dataDir;
1601     return storeInfo;
1602 }
1603 
LockCloudContainer(const RdbSyncerParam & param)1604 std::pair<int32_t, uint32_t> RdbServiceImpl::LockCloudContainer(const RdbSyncerParam &param)
1605 {
1606     std::pair<int32_t, uint32_t> result { RDB_ERROR, 0 };
1607     if (!IsValidAccess(param.bundleName_, param.storeName_)) {
1608         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
1609               Anonymous::Change(param.storeName_).c_str());
1610         return result;
1611     }
1612     ZLOGI("start to lock cloud db: bundleName:%{public}s, storeName:%{public}s", param.bundleName_.c_str(),
1613         Anonymous::Change(param.storeName_).c_str());
1614 
1615     auto storeInfo = GetStoreInfo(param);
1616 
1617     CloudLockEvent::Callback callback = [&result](int32_t status, uint32_t expiredTime) {
1618         result.first = status;
1619         result.second = expiredTime;
1620     };
1621     auto evt = std::make_unique<CloudLockEvent>(CloudEvent::LOCK_CLOUD_CONTAINER, std::move(storeInfo), callback);
1622     EventCenter::GetInstance().PostEvent(std::move(evt));
1623     return result;
1624 }
1625 
UnlockCloudContainer(const RdbSyncerParam & param)1626 int32_t RdbServiceImpl::UnlockCloudContainer(const RdbSyncerParam &param)
1627 {
1628     int32_t result = RDB_ERROR;
1629     if (!IsValidAccess(param.bundleName_, param.storeName_)) {
1630         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
1631               Anonymous::Change(param.storeName_).c_str());
1632         return result;
1633     }
1634     ZLOGI("start to unlock cloud db: bundleName:%{public}s, storeName:%{public}s", param.bundleName_.c_str(),
1635         Anonymous::Change(param.storeName_).c_str());
1636 
1637     auto storeInfo = GetStoreInfo(param);
1638 
1639     CloudLockEvent::Callback callback = [&result](int32_t status, uint32_t expiredTime) {
1640         (void)expiredTime;
1641         result = status;
1642     };
1643     auto evt = std::make_unique<CloudLockEvent>(CloudEvent::UNLOCK_CLOUD_CONTAINER, std::move(storeInfo), callback);
1644     EventCenter::GetInstance().PostEvent(std::move(evt));
1645     return result;
1646 }
1647 
GetDebugInfo(const RdbSyncerParam & param,std::map<std::string,RdbDebugInfo> & debugInfo)1648 int32_t RdbServiceImpl::GetDebugInfo(const RdbSyncerParam &param, std::map<std::string, RdbDebugInfo> &debugInfo)
1649 {
1650     if (!IsValidAccess(param.bundleName_, param.storeName_)) {
1651         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
1652             Anonymous::Change(param.storeName_).c_str());
1653         return RDB_ERROR;
1654     }
1655     auto metaData = GetStoreMetaData(param);
1656     auto isCreated = MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData, true);
1657     if (!isCreated) {
1658         ZLOGE("bundleName:%{public}s, storeName:%{public}s. no meta data", param.bundleName_.c_str(),
1659             Anonymous::Change(param.storeName_).c_str());
1660         return RDB_OK;
1661     }
1662     DistributedData::StoreDebugInfo debugMeta;
1663     isCreated = MetaDataManager::GetInstance().LoadMeta(metaData.GetDebugInfoKey(), debugMeta, true);
1664     if (!isCreated) {
1665         return RDB_OK;
1666     }
1667 
1668     for (auto &[name, fileDebug] : debugMeta.fileInfos) {
1669         RdbDebugInfo rdbInfo;
1670         rdbInfo.inode_ = fileDebug.inode;
1671         rdbInfo.size_ = fileDebug.size;
1672         rdbInfo.dev_ = fileDebug.dev;
1673         rdbInfo.mode_ = fileDebug.mode;
1674         rdbInfo.uid_ = fileDebug.uid;
1675         rdbInfo.gid_ = fileDebug.gid;
1676         debugInfo.insert(std::pair{ name, rdbInfo });
1677     }
1678     return RDB_OK;
1679 }
1680 
SaveDebugInfo(const StoreMetaData & metaData,const RdbSyncerParam & param)1681 int32_t RdbServiceImpl::SaveDebugInfo(const StoreMetaData &metaData, const RdbSyncerParam &param)
1682 {
1683     if (param.infos_.empty()) {
1684         return RDB_OK;
1685     }
1686     DistributedData::StoreDebugInfo debugMeta;
1687     for (auto &[name, info] : param.infos_) {
1688         DistributedData::StoreDebugInfo::FileInfo fileInfo;
1689         fileInfo.inode = info.inode_;
1690         fileInfo.size = info.size_;
1691         fileInfo.dev = info.dev_;
1692         fileInfo.mode = info.mode_;
1693         fileInfo.uid = info.uid_;
1694         fileInfo.gid = info.gid_;
1695         debugMeta.fileInfos.insert(std::pair{name, fileInfo});
1696     }
1697     MetaDataManager::GetInstance().SaveMeta(metaData.GetDebugInfoKey(), debugMeta, true);
1698     return RDB_OK;
1699 }
1700 
GetDfxInfo(const RdbSyncerParam & param,DistributedRdb::RdbDfxInfo & dfxInfo)1701 int32_t RdbServiceImpl::GetDfxInfo(const RdbSyncerParam &param, DistributedRdb::RdbDfxInfo &dfxInfo)
1702 {
1703     if (!IsValidAccess(param.bundleName_, param.storeName_)) {
1704         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
1705             Anonymous::Change(param.storeName_).c_str());
1706         return RDB_ERROR;
1707     }
1708     auto metaData = GetStoreMetaData(param);
1709     auto isCreated = MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData, true);
1710     if (!isCreated) {
1711         ZLOGI("bundleName:%{public}s, storeName:%{public}s. no meta data", param.bundleName_.c_str(),
1712             Anonymous::Change(param.storeName_).c_str());
1713         return RDB_OK;
1714     }
1715     DistributedData::StoreDfxInfo dfxMeta;
1716     isCreated = MetaDataManager::GetInstance().LoadMeta(metaData.GetDfxInfoKey(), dfxMeta, true);
1717     if (!isCreated) {
1718         ZLOGI("bundleName:%{public}s, storeName:%{public}s. no dfx meta data", param.bundleName_.c_str(),
1719             Anonymous::Change(param.storeName_).c_str());
1720         return RDB_OK;
1721     }
1722     dfxInfo.lastOpenTime_ = dfxMeta.lastOpenTime;
1723     DistributedData::AccountDelegate *instance = DistributedData::AccountDelegate::GetInstance();
1724     if (instance != nullptr) {
1725         (void)instance->QueryForegroundUserId(dfxInfo.curUserId_);
1726     }
1727     return RDB_OK;
1728 }
1729 
SaveDfxInfo(const StoreMetaData & metaData,const RdbSyncerParam & param)1730 int32_t RdbServiceImpl::SaveDfxInfo(const StoreMetaData &metaData, const RdbSyncerParam &param)
1731 {
1732     DistributedData::StoreDfxInfo dfxMeta;
1733     dfxMeta.lastOpenTime = param.dfxInfo_.lastOpenTime_;
1734     MetaDataManager::GetInstance().SaveMeta(metaData.GetDfxInfoKey(), dfxMeta, true);
1735     return RDB_OK;
1736 }
1737 
SavePromiseInfo(const StoreMetaData & metaData,const RdbSyncerParam & param)1738 int32_t RdbServiceImpl::SavePromiseInfo(const StoreMetaData &metaData, const RdbSyncerParam &param)
1739 {
1740     if (param.tokenIds_.empty() && param.uids_.empty()) {
1741         return RDB_OK;
1742     }
1743     StoreMetaDataLocal localMeta;
1744     localMeta.promiseInfo.tokenIds = param.tokenIds_;
1745     localMeta.promiseInfo.uids = param.uids_;
1746     localMeta.promiseInfo.permissionNames = param.permissionNames_;
1747     MetaDataManager::GetInstance().SaveMeta(metaData.GetKeyLocal(), localMeta, true);
1748     return RDB_OK;
1749 }
1750 
VerifyPromiseInfo(const RdbSyncerParam & param)1751 int32_t RdbServiceImpl::VerifyPromiseInfo(const RdbSyncerParam &param)
1752 {
1753     XCollie xcollie(__FUNCTION__, XCollie::XCOLLIE_LOG | XCollie::XCOLLIE_RECOVERY);
1754     auto meta = GetStoreMetaData(param);
1755     auto tokenId = IPCSkeleton::GetCallingTokenID();
1756     auto uid = IPCSkeleton::GetCallingUid();
1757     meta.user = param.user_;
1758     StoreMetaDataLocal localMeta;
1759     if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKeyLocal(), localMeta, true)) {
1760         StoreMetaMapping metaMapping(meta);
1761         MetaDataManager::GetInstance().LoadMeta(metaMapping.GetKey(), metaMapping, true);
1762         meta.dataDir = metaMapping.dataDir;
1763         if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKeyLocal(), localMeta, true)) {
1764             ZLOGE("Store not exist. bundleName:%{public}s, storeName:%{public}s", meta.bundleName.c_str(),
1765                 meta.GetStoreAlias().c_str());
1766             return RDB_ERROR;
1767         }
1768     }
1769     ATokenTypeEnum type = AccessTokenKit::GetTokenType(tokenId);
1770     if (type == ATokenTypeEnum::TOKEN_NATIVE || type == ATokenTypeEnum::TOKEN_SHELL) {
1771         auto tokenIdRet =
1772             std::find(localMeta.promiseInfo.tokenIds.begin(), localMeta.promiseInfo.tokenIds.end(), tokenId);
1773         auto uidRet = std::find(localMeta.promiseInfo.uids.begin(), localMeta.promiseInfo.uids.end(), uid);
1774         bool isPromise = std::any_of(localMeta.promiseInfo.permissionNames.begin(),
1775             localMeta.promiseInfo.permissionNames.end(), [tokenId](const std::string &permissionName) {
1776                 return PermitDelegate::VerifyPermission(permissionName, tokenId);
1777         });
1778         if (tokenIdRet == localMeta.promiseInfo.tokenIds.end() && uidRet == localMeta.promiseInfo.uids.end() &&
1779             !isPromise) {
1780             return RDB_ERROR;
1781         }
1782     } else if (type == ATokenTypeEnum::TOKEN_HAP) {
1783         for (const auto &permissionName : localMeta.promiseInfo.permissionNames) {
1784             if (PermitDelegate::VerifyPermission(permissionName, tokenId)) {
1785                 return RDB_OK;
1786             }
1787         }
1788         ZLOGE("Permission denied! tokenId:0x%{public}x", tokenId);
1789         return RDB_ERROR;
1790     } else {
1791         ZLOGE("invalid type! bundleName:%{public}s, storeName:%{public}s, token_type is %{public}d.",
1792             meta.bundleName.c_str(), meta.GetStoreAlias().c_str(), type);
1793         return RDB_ERROR;
1794     }
1795     return RDB_OK;
1796 }
1797 
GetSubUser(const int32_t subUser)1798 std::string RdbServiceImpl::GetSubUser(const int32_t subUser)
1799 {
1800     std::string userId = "";
1801     if (AccessTokenKit::GetTokenTypeFlag(IPCSkeleton::GetCallingTokenID()) != TOKEN_HAP && subUser != 0) {
1802         userId = std::to_string(subUser);
1803     }
1804     return userId;
1805 }
1806 
TryUpdateDeviceId(const RdbSyncerParam & param,const StoreMetaData & oldMeta,StoreMetaData & meta)1807 bool RdbServiceImpl::TryUpdateDeviceId(const RdbSyncerParam &param, const StoreMetaData &oldMeta,
1808     StoreMetaData &meta)
1809 {
1810     StoreMetaData syncMeta;
1811     if (oldMeta.isNeedUpdateDeviceId && oldMeta.storeType >= StoreMetaData::StoreType::STORE_RELATIONAL_BEGIN &&
1812         oldMeta.storeType <= StoreMetaData::StoreType::STORE_RELATIONAL_END &&
1813         MetaDataManager::GetInstance().LoadMeta(meta.GetKeyWithoutPath(), syncMeta)) {
1814         auto store = GetStore(param);
1815         if (store == nullptr) {
1816             ZLOGE("store is null, bundleName:%{public}s storeName:%{public}s", param.bundleName_.c_str(),
1817                 Anonymous::Change(param.storeName_).c_str());
1818             return false;
1819         }
1820         auto errCode = store->UpdateDBStatus();
1821         if (errCode != RDB_OK) {
1822             ZLOGE("Update failed errCode %{public}d", errCode);
1823             return false;
1824         }
1825     }
1826     return true;
1827 }
1828 
RegisterEvent()1829 void RdbServiceImpl::RegisterEvent()
1830 {
1831     auto process = [this](const Event &event) {
1832         auto &evt = static_cast<const CloudEvent &>(event);
1833         auto &storeInfo = evt.GetStoreInfo();
1834         StoreMetaMapping mapping(storeInfo);
1835         mapping.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
1836         if (!MetaDataManager::GetInstance().LoadMeta(mapping.GetKey(), mapping, true)) {
1837             ZLOGE("bundle:%{public}s, storeId:%{public}s", mapping.bundleName.c_str(), mapping.GetStoreAlias().c_str());
1838             return;
1839         }
1840         StoreMetaData meta = mapping;
1841         if (!mapping.cloudPath.empty() && mapping.cloudPath != mapping.dataDir &&
1842             !MetaDataManager::GetInstance().LoadMeta(mapping.GetCloudStoreMetaKey(), meta, true)) {
1843             ZLOGE("meta empty, bundleName:%{public}s, storeId:%{public}s", meta.bundleName.c_str(),
1844                 meta.GetStoreAlias().c_str());
1845             return;
1846         }
1847         if (meta.storeType < StoreMetaData::STORE_RELATIONAL_BEGIN ||
1848             meta.storeType > StoreMetaData::STORE_RELATIONAL_END) {
1849             return;
1850         }
1851         auto watchers = GetWatchers(meta.tokenId, meta.storeId);
1852         auto store = AutoCache::GetInstance().GetStore(meta, watchers);
1853         if (store == nullptr) {
1854             ZLOGE("store null, storeId:%{public}s", meta.GetStoreAlias().c_str());
1855             return;
1856         }
1857         store->RegisterDetailProgressObserver(GetCallbacks(meta.tokenId, storeInfo.storeName));
1858     };
1859     EventCenter::GetInstance().Subscribe(CloudEvent::CLOUD_SYNC, process);
1860     EventCenter::GetInstance().Subscribe(CloudEvent::CLEAN_DATA, process);
1861 
1862     EventCenter::GetInstance().Subscribe(CloudEvent::MAKE_QUERY, [](const Event &event) {
1863         auto &evt = static_cast<const MakeQueryEvent &>(event);
1864         auto callback = evt.GetCallback();
1865         if (!callback) {
1866             return;
1867         }
1868         auto predicate = evt.GetPredicates();
1869         auto rdbQuery = std::make_shared<RdbQuery>();
1870         rdbQuery->MakeQuery(*predicate);
1871         rdbQuery->SetColumns(evt.GetColumns());
1872         callback(rdbQuery);
1873     });
1874     auto compensateSyncProcess = [this](const Event &event) {
1875         auto &evt = static_cast<const BindEvent &>(event);
1876         DoCompensateSync(evt);
1877     };
1878     EventCenter::GetInstance().Subscribe(BindEvent::COMPENSATE_SYNC, compensateSyncProcess);
1879     EventCenter::GetInstance().Subscribe(BindEvent::RECOVER_SYNC, compensateSyncProcess);
1880 }
1881 
GetPath(const RdbSyncerParam & param)1882 std::string RdbServiceImpl::GetPath(const RdbSyncerParam &param)
1883 {
1884     StoreMetaData metaData;
1885     metaData.uid = IPCSkeleton::GetCallingUid();
1886     metaData.tokenId = IPCSkeleton::GetCallingTokenID();
1887     auto [instanceId, user] = GetInstIndexAndUser(metaData.tokenId, param.bundleName_);
1888     metaData.instanceId = instanceId;
1889     metaData.bundleName = param.bundleName_;
1890     metaData.storeId = RemoveSuffix(param.storeName_);
1891     if (AccessTokenKit::GetTokenTypeFlag(metaData.tokenId) != TOKEN_HAP && param.subUser_ != 0) {
1892         metaData.user = std::to_string(param.subUser_);
1893     } else {
1894         metaData.user = std::to_string(user);
1895     }
1896     metaData.storeType = param.type_;
1897     metaData.securityLevel = param.level_;
1898     metaData.area = param.area_;
1899     metaData.appType = "harmony";
1900     metaData.hapName = param.hapName_;
1901     metaData.customDir = param.customDir_;
1902     return DirectoryManager::GetInstance().GetStorePath(metaData) + "/" + param.storeName_;
1903 }
1904 
1905 } // namespace OHOS::DistributedRdb