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 ¶m) {
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 ¶m)
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 ¶m, 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 ¶m, 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 ¶m)
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 ¶m, 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, [¬ifier, 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, ¬ifiers](auto, SyncAgents &syncAgents) {
404 std::for_each(syncAgents.begin(), syncAgents.end(), [&storeName, ¬ifiers](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 ¬ifier : 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 ¶m, 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 ¶m, 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 ¶m, 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, ¶m](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 ¶m, 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, ¶m, &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 ¶m, 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, ¶m, &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 ¶m)
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 ¶m)
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 ¶m)
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 ¶m)
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 ¶m)
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 ¶m)
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 ¶m)
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 ¶m)
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 ¶m)
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 ¶m, 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>> ¶ms)
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 ¶m, 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 ¶m)
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 ¶m)
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 ¶m, 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 ¶m)
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 ¶m)
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 ¶m)
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 ¶m, 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 ¶m)
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 ¶m, 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 ¶m)
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 ¶m)
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 ¶m)
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 ¶m, 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 ¶m)
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