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