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