• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #define LOG_TAG "RdbServiceImpl"
16 #include "rdb_service_impl.h"
17 
18 #include "abs_rdb_predicates.h"
19 #include "accesstoken_kit.h"
20 #include "account/account_delegate.h"
21 #include "changeevent/remote_change_event.h"
22 #include "checker/checker_manager.h"
23 #include "cloud/change_event.h"
24 #include "cloud/cloud_lock_event.h"
25 #include "cloud/cloud_share_event.h"
26 #include "cloud/make_query_event.h"
27 #include "cloud/schema_meta.h"
28 #include "communicator/device_manager_adapter.h"
29 #include "crypto_manager.h"
30 #include "device_matrix.h"
31 #include "directory/directory_manager.h"
32 #include "dump/dump_manager.h"
33 #include "eventcenter/event_center.h"
34 #include "ipc_skeleton.h"
35 #include "log_print.h"
36 #include "metadata/appid_meta_data.h"
37 #include "metadata/auto_launch_meta_data.h"
38 #include "metadata/capability_meta_data.h"
39 #include "metadata/meta_data_manager.h"
40 #include "metadata/store_debug_info.h"
41 #include "metadata/store_meta_data.h"
42 #include "rdb_general_store.h"
43 #include "rdb_notifier_proxy.h"
44 #include "rdb_query.h"
45 #include "rdb_result_set_impl.h"
46 #include "rdb_watcher.h"
47 #include "store/general_store.h"
48 #include "tokenid_kit.h"
49 #include "types_export.h"
50 #include "utils/anonymous.h"
51 #include "utils/constant.h"
52 #include "utils/converter.h"
53 #include "xcollie.h"
54 using OHOS::DistributedKv::AccountDelegate;
55 using OHOS::DistributedData::CheckerManager;
56 using OHOS::DistributedData::MetaDataManager;
57 using OHOS::DistributedData::StoreMetaData;
58 using OHOS::DistributedData::Anonymous;
59 using namespace OHOS::DistributedData;
60 using namespace OHOS::Security::AccessToken;
61 using DistributedDB::RelationalStoreManager;
62 using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter;
63 using DumpManager = OHOS::DistributedData::DumpManager;
64 using system_clock = std::chrono::system_clock;
65 
66 constexpr uint32_t ITERATE_TIMES = 10000;
67 namespace OHOS::DistributedRdb {
68 __attribute__((used)) RdbServiceImpl::Factory RdbServiceImpl::factory_;
Factory()69 RdbServiceImpl::Factory::Factory()
70 {
71     FeatureSystem::GetInstance().RegisterCreator(RdbServiceImpl::SERVICE_NAME, [this]() {
72         if (product_ == nullptr) {
73             product_ = std::make_shared<RdbServiceImpl>();
74         }
75         return product_;
76     });
77     AutoCache::GetInstance().RegCreator(RDB_DEVICE_COLLABORATION, [](const StoreMetaData& metaData) -> GeneralStore* {
78         auto store = new (std::nothrow) RdbGeneralStore(metaData);
79         if (store != nullptr && !store->IsValid()) {
80             delete store;
81             store = nullptr;
82         }
83         return store;
84     });
85     staticActs_ = std::make_shared<RdbStatic>();
86     FeatureSystem::GetInstance().RegisterStaticActs(RdbServiceImpl::SERVICE_NAME, staticActs_);
87 }
88 
~Factory()89 RdbServiceImpl::Factory::~Factory()
90 {
91 }
92 
RdbServiceImpl()93 RdbServiceImpl::RdbServiceImpl()
94 {
95     ZLOGI("construct");
96     DistributedDB::RelationalStoreManager::SetAutoLaunchRequestCallback(
97         [this](const std::string& identifier, DistributedDB::AutoLaunchParam &param) {
98             return ResolveAutoLaunch(identifier, param);
99         });
100     auto process = [this](const Event &event) {
101         auto &evt = static_cast<const CloudEvent &>(event);
102         auto &storeInfo = evt.GetStoreInfo();
103         StoreMetaData meta(storeInfo);
104         meta.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
105         if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true)) {
106             ZLOGE("meta empty, bundleName:%{public}s, storeId:%{public}s", meta.bundleName.c_str(),
107                 meta.GetStoreAlias().c_str());
108             return;
109         }
110         if (meta.storeType < StoreMetaData::STORE_RELATIONAL_BEGIN ||
111             meta.storeType > StoreMetaData::STORE_RELATIONAL_END) {
112             return;
113         }
114         auto watchers = GetWatchers(meta.tokenId, meta.storeId);
115         auto store = AutoCache::GetInstance().GetStore(meta, watchers);
116         if (store == nullptr) {
117             ZLOGE("store null, storeId:%{public}s", meta.GetStoreAlias().c_str());
118             return;
119         }
120         store->RegisterDetailProgressObserver(GetCallbacks(meta.tokenId, storeInfo.storeName));
121     };
122     EventCenter::GetInstance().Subscribe(CloudEvent::CLOUD_SYNC, process);
123     EventCenter::GetInstance().Subscribe(CloudEvent::CLEAN_DATA, process);
124 
125     EventCenter::GetInstance().Subscribe(CloudEvent::MAKE_QUERY, [](const Event& event) {
126         auto& evt = static_cast<const MakeQueryEvent&>(event);
127         auto callback = evt.GetCallback();
128         if (!callback) {
129             return;
130         }
131         auto predicate = evt.GetPredicates();
132         auto rdbQuery = std::make_shared<RdbQuery>();
133         rdbQuery->MakeQuery(*predicate);
134         rdbQuery->SetColumns(evt.GetColumns());
135         callback(rdbQuery);
136     });
137     auto compensateSyncProcess = [this] (const Event &event) {
138         auto &evt = static_cast<const BindEvent &>(event);
139         DoCompensateSync(evt);
140     };
141     EventCenter::GetInstance().Subscribe(BindEvent::COMPENSATE_SYNC, compensateSyncProcess);
142     EventCenter::GetInstance().Subscribe(BindEvent::RECOVER_SYNC, compensateSyncProcess);
143 }
144 
ResolveAutoLaunch(const std::string & identifier,DistributedDB::AutoLaunchParam & param)145 int32_t RdbServiceImpl::ResolveAutoLaunch(const std::string &identifier, DistributedDB::AutoLaunchParam &param)
146 {
147     std::string identifierHex = TransferStringToHex(identifier);
148     ZLOGI("%{public}.6s", identifierHex.c_str());
149     std::vector<StoreMetaData> entries;
150     auto localId = DmAdapter::GetInstance().GetLocalDevice().uuid;
151     if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ localId }), entries)) {
152         ZLOGE("get meta failed");
153         return false;
154     }
155     ZLOGI("size=%{public}d", static_cast<int32_t>(entries.size()));
156     for (const auto& entry : entries) {
157         if (entry.storeType != RDB_DEVICE_COLLABORATION) {
158             continue;
159         }
160 
161         auto aIdentifier = DistributedDB::RelationalStoreManager::GetRelationalStoreIdentifier(
162             entry.user, entry.appId, entry.storeId);
163         ZLOGD("%{public}s %{public}s %{public}s",
164             entry.user.c_str(), entry.appId.c_str(), Anonymous::Change(entry.storeId).c_str());
165         if (aIdentifier != identifier) {
166             continue;
167         }
168         ZLOGI("find identifier %{public}s", Anonymous::Change(entry.storeId).c_str());
169         param.userId = entry.user;
170         param.appId = entry.appId;
171         param.storeId = entry.storeId;
172         param.path = entry.dataDir;
173         param.option.storeObserver = nullptr;
174         param.option.isEncryptedDb = entry.isEncrypt;
175         if (entry.isEncrypt) {
176             param.option.iterateTimes = ITERATE_TIMES;
177             param.option.cipher = DistributedDB::CipherType::AES_256_GCM;
178             GetDBPassword(entry, param.option.passwd);
179         }
180         AutoCache::GetInstance().GetStore(entry, GetWatchers(entry.tokenId, entry.storeId));
181         return true;
182     }
183     ZLOGE("not find identifier");
184     return false;
185 }
186 
OnAppExit(pid_t uid,pid_t pid,uint32_t tokenId,const std::string & bundleName)187 int32_t RdbServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &bundleName)
188 {
189     ZLOGI("client dead, tokenId:%{public}d, pid:%{public}d ", tokenId, pid);
190     bool destroyed = false;
191     syncAgents_.ComputeIfPresent(tokenId, [pid, &destroyed](auto &key, SyncAgents &agents) {
192         auto it = agents.find(pid);
193         if (it != agents.end()) {
194             it->second.SetNotifier(nullptr);
195             agents.erase(it);
196         }
197         if (!agents.empty()) {
198             return true;
199         }
200         destroyed = true;
201         return false;
202     });
203     if (destroyed) {
204         auto stores = AutoCache::GetInstance().GetStoresIfPresent(tokenId);
205         for (auto store : stores) {
206             if (store != nullptr) {
207                 store->UnregisterDetailProgressObserver();
208             }
209         }
210         AutoCache::GetInstance().Enable(tokenId);
211     }
212     heartbeatTaskIds_.Erase(pid);
213     return E_OK;
214 }
215 
CheckAccess(const std::string & bundleName,const std::string & storeName)216 bool RdbServiceImpl::CheckAccess(const std::string& bundleName, const std::string& storeName)
217 {
218     CheckerManager::StoreInfo storeInfo;
219     storeInfo.uid = IPCSkeleton::GetCallingUid();
220     storeInfo.tokenId = IPCSkeleton::GetCallingTokenID();
221     storeInfo.bundleName = bundleName;
222     storeInfo.storeId = RemoveSuffix(storeName);
223     auto [instanceId, user] = GetInstIndexAndUser(storeInfo.tokenId, storeInfo.bundleName);
224     if (instanceId != 0) {
225         return false;
226     }
227     return !CheckerManager::GetInstance().GetAppId(storeInfo).empty();
228 }
229 
ObtainDistributedTableName(const std::string & device,const std::string & table)230 std::string RdbServiceImpl::ObtainDistributedTableName(const std::string &device, const std::string &table)
231 {
232     ZLOGI("device=%{public}s table=%{public}s", Anonymous::Change(device).c_str(), table.c_str());
233     auto uuid = DmAdapter::GetInstance().GetUuidByNetworkId(device);
234     if (uuid.empty()) {
235         ZLOGE("get uuid failed");
236         return "";
237     }
238     return DistributedDB::RelationalStoreManager::GetDistributedTableName(uuid, table);
239 }
240 
InitNotifier(const RdbSyncerParam & param,const sptr<IRemoteObject> notifier)241 int32_t RdbServiceImpl::InitNotifier(const RdbSyncerParam &param, const sptr<IRemoteObject> notifier)
242 {
243     XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY);
244     if (!CheckAccess(param.bundleName_, "")) {
245         ZLOGE("bundleName:%{public}s. Permission error", param.bundleName_.c_str());
246         return RDB_ERROR;
247     }
248     if (notifier == nullptr) {
249         ZLOGE("notifier is null");
250         return RDB_ERROR;
251     }
252 
253     auto notifierProxy = iface_cast<RdbNotifierProxy>(notifier);
254     pid_t pid = IPCSkeleton::GetCallingPid();
255     uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
256     syncAgents_.Compute(tokenId, [bundleName = param.bundleName_, notifierProxy, pid](auto, SyncAgents &agents) {
257         auto [it, success] = agents.try_emplace(pid, SyncAgent(bundleName));
258         if (it == agents.end()) {
259             return true;
260         }
261         it->second.SetNotifier(notifierProxy);
262         return true;
263     });
264     ZLOGI("success tokenId:%{public}x, pid=%{public}d", tokenId, pid);
265     return RDB_OK;
266 }
267 
GetStore(const RdbSyncerParam & param)268 std::shared_ptr<DistributedData::GeneralStore> RdbServiceImpl::GetStore(const RdbSyncerParam &param)
269 {
270     StoreMetaData storeMetaData = GetStoreMetaData(param);
271     MetaDataManager::GetInstance().LoadMeta(storeMetaData.GetKey(), storeMetaData, true);
272     auto watchers = GetWatchers(storeMetaData.tokenId, storeMetaData.storeId);
273     auto store = AutoCache::GetInstance().GetStore(storeMetaData, watchers);
274     if (store == nullptr) {
275         ZLOGE("store null, storeId:%{public}s", storeMetaData.GetStoreAlias().c_str());
276     }
277     return store;
278 }
279 
SetDistributedTables(const RdbSyncerParam & param,const std::vector<std::string> & tables,const std::vector<Reference> & references,bool isRebuild,int32_t type)280 int32_t RdbServiceImpl::SetDistributedTables(const RdbSyncerParam &param, const std::vector<std::string> &tables,
281     const std::vector<Reference> &references, bool isRebuild, int32_t type)
282 {
283     if (!CheckAccess(param.bundleName_, param.storeName_)) {
284         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
285             Anonymous::Change(param.storeName_).c_str());
286         return RDB_ERROR;
287     }
288     if (type == DistributedRdb::DistributedTableType::DISTRIBUTED_SEARCH) {
289         DistributedData::SetSearchableEvent::EventInfo eventInfo;
290         eventInfo.isRebuild = isRebuild;
291         return PostSearchEvent(CloudEvent::SET_SEARCH_TRIGGER, param, eventInfo);
292     }
293     auto meta = GetStoreMetaData(param);
294 
295     if (type == DistributedRdb::DistributedTableType::DISTRIBUTED_DEVICE) {
296         StoreMetaData localMeta;
297         bool isCreatedLocal = MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), localMeta, true);
298         if (!isCreatedLocal) {
299             ZLOGE("no meta. bundleName:%{public}s, storeName:%{public}s. GetStore failed", param.bundleName_.c_str(),
300                 Anonymous::Change(param.storeName_).c_str());
301             return RDB_ERROR;
302         }
303         StoreMetaData syncMeta;
304         bool isCreatedSync = MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), syncMeta);
305         if (!isCreatedSync || localMeta != syncMeta) {
306             ZLOGI("save sync meta. bundle:%{public}s store:%{public}s type:%{public}d->%{public}d "
307                   "encrypt:%{public}d->%{public}d , area:%{public}d->%{public}d",
308                 meta.bundleName.c_str(), meta.GetStoreAlias().c_str(), syncMeta.storeType, meta.storeType,
309                 syncMeta.isEncrypt, meta.isEncrypt, syncMeta.area, meta.area);
310             MetaDataManager::GetInstance().SaveMeta(meta.GetKey(), localMeta);
311         }
312     }
313     auto store = GetStore(param);
314     if (store == nullptr) {
315         ZLOGE("bundleName:%{public}s, storeName:%{public}s. GetStore failed", param.bundleName_.c_str(),
316             Anonymous::Change(param.storeName_).c_str());
317         return RDB_ERROR;
318     }
319     std::vector<DistributedData::Reference> relationships;
320     for (const auto &reference : references) {
321         DistributedData::Reference relationship = { reference.sourceTable, reference.targetTable, reference.refFields };
322         relationships.emplace_back(relationship);
323     }
324     return store->SetDistributedTables(tables, type, relationships);
325 }
326 
OnAsyncComplete(uint32_t tokenId,pid_t pid,uint32_t seqNum,Details && result)327 void RdbServiceImpl::OnAsyncComplete(uint32_t tokenId, pid_t pid, uint32_t seqNum, Details &&result)
328 {
329     ZLOGI("tokenId=%{public}x, pid=%{public}d, seqnum=%{public}u", tokenId, pid, seqNum);
330     sptr<RdbNotifierProxy> notifier = nullptr;
331     syncAgents_.ComputeIfPresent(tokenId, [&notifier, pid](auto, SyncAgents &syncAgents) {
332         auto it = syncAgents.find(pid);
333         if (it != syncAgents.end()) {
334             notifier = it->second.notifier_;
335         }
336         return true;
337     });
338     if (notifier != nullptr) {
339         notifier->OnComplete(seqNum, std::move(result));
340     }
341 }
342 
TransferStringToHex(const std::string & origStr)343 std::string RdbServiceImpl::TransferStringToHex(const std::string &origStr)
344 {
345     if (origStr.empty()) {
346         return "";
347     }
348     const char *hex = "0123456789abcdef";
349     std::string tmp;
350     for (auto item : origStr) {
351         auto currentByte = static_cast<uint8_t>(item);
352         tmp.push_back(hex[currentByte >> 4]); // high 4 bit to one hex.
353         tmp.push_back(hex[currentByte & 0x0F]); // low 4 bit to one hex.
354     }
355     return tmp;
356 }
357 
GetWatchers(uint32_t tokenId,const std::string & storeName)358 AutoCache::Watchers RdbServiceImpl::GetWatchers(uint32_t tokenId, const std::string &storeName)
359 {
360     AutoCache::Watchers watchers;
361     syncAgents_.ComputeIfPresent(tokenId, [&watchers](auto, SyncAgents &syncAgents) {
362         std::for_each(syncAgents.begin(), syncAgents.end(), [&watchers](const auto &item) {
363             if (item.second.watcher_ != nullptr) {
364                 watchers.insert(item.second.watcher_);
365             }
366         });
367         return true;
368     });
369     return watchers;
370 }
371 
GetCallbacks(uint32_t tokenId,const std::string & storeName)372 RdbServiceImpl::DetailAsync RdbServiceImpl::GetCallbacks(uint32_t tokenId, const std::string &storeName)
373 {
374     std::list<sptr<RdbNotifierProxy>> notifiers;
375     syncAgents_.ComputeIfPresent(tokenId, [&storeName, &notifiers](auto, SyncAgents &syncAgents) {
376         std::for_each(syncAgents.begin(), syncAgents.end(), [&storeName, &notifiers](const auto &item) {
377             if (item.second.callBackStores_.count(storeName) != 0) {
378                 notifiers.push_back(item.second.notifier_);
379             }
380         });
381         return true;
382     });
383     if (notifiers.empty()) {
384         return nullptr;
385     }
386     return [notifiers, storeName](const GenDetails &details) {
387         for (const auto &notifier : notifiers) {
388             if (notifier != nullptr) {
389                 notifier->OnComplete(storeName, HandleGenDetails(details));
390             }
391         }
392     };
393 }
394 
RemoteQuery(const RdbSyncerParam & param,const std::string & device,const std::string & sql,const std::vector<std::string> & selectionArgs)395 std::pair<int32_t, std::shared_ptr<RdbServiceImpl::ResultSet>> RdbServiceImpl::RemoteQuery(const RdbSyncerParam& param,
396     const std::string& device, const std::string& sql, const std::vector<std::string>& selectionArgs)
397 {
398     if (!CheckAccess(param.bundleName_, param.storeName_)) {
399         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
400             Anonymous::Change(param.storeName_).c_str());
401         return { RDB_ERROR, nullptr };
402     }
403     auto store = GetStore(param);
404     if (store == nullptr) {
405         ZLOGE("store is null");
406         return { RDB_ERROR, nullptr };
407     }
408     RdbQuery rdbQuery;
409     rdbQuery.MakeRemoteQuery(DmAdapter::GetInstance().ToUUID(device), sql, ValueProxy::Convert(selectionArgs));
410     auto [errCode, cursor] = store->Query("", rdbQuery);
411     if (errCode != GeneralError::E_OK) {
412         return { RDB_ERROR, nullptr };
413     }
414     return { RDB_OK, std::make_shared<RdbResultSetImpl>(cursor) };
415 }
416 
Sync(const RdbSyncerParam & param,const Option & option,const PredicatesMemo & predicates,const AsyncDetail & async)417 int32_t RdbServiceImpl::Sync(const RdbSyncerParam &param, const Option &option, const PredicatesMemo &predicates,
418                              const AsyncDetail &async)
419 {
420     if (!CheckAccess(param.bundleName_, param.storeName_)) {
421         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
422             Anonymous::Change(param.storeName_).c_str());
423         return RDB_ERROR;
424     }
425     if (option.mode < DistributedData::GeneralStore::CLOUD_END &&
426         option.mode >= DistributedData::GeneralStore::CLOUD_BEGIN) {
427         DoCloudSync(param, option, predicates, async);
428         return RDB_OK;
429     }
430     return DoSync(param, option, predicates, async);
431 }
432 
DoSync(const RdbSyncerParam & param,const RdbService::Option & option,const PredicatesMemo & predicates,const AsyncDetail & async)433 int RdbServiceImpl::DoSync(const RdbSyncerParam &param, const RdbService::Option &option,
434     const PredicatesMemo &predicates, const AsyncDetail &async)
435 {
436     auto store = GetStore(param);
437     if (store == nullptr) {
438         return RDB_ERROR;
439     }
440     RdbQuery rdbQuery;
441     rdbQuery.MakeQuery(predicates);
442     auto devices = rdbQuery.GetDevices().empty() ? DmAdapter::ToUUID(DmAdapter::GetInstance().GetRemoteDevices())
443                                                  : DmAdapter::ToUUID(rdbQuery.GetDevices());
444     auto pid = IPCSkeleton::GetCallingPid();
445     SyncParam syncParam = { option.mode, 0, option.isCompensation };
446     StoreMetaData meta = GetStoreMetaData(param);
447     auto tokenId = IPCSkeleton::GetCallingTokenID();
448     ZLOGD("seqNum=%{public}u", option.seqNum);
449     auto complete = [this, rdbQuery, store, pid, syncParam, tokenId, async, seq = option.seqNum](
450                         const auto &results) mutable {
451         auto ret = ProcessResult(results);
452         store->Sync(
453             ret.first, rdbQuery,
454             [this, tokenId, seq, pid](const GenDetails &result) mutable {
455                 OnAsyncComplete(tokenId, pid, seq, HandleGenDetails(result));
456             },
457             syncParam);
458     };
459     if (IsNeedMetaSync(meta, devices)) {
460         auto result = MetaDataManager::GetInstance().Sync(devices, complete);
461         return result ? GeneralError::E_OK : GeneralError::E_ERROR;
462     }
463     return store->Sync(
464         devices, rdbQuery,
465         [this, tokenId, pid, seqNum = option.seqNum](const GenDetails &result) mutable {
466             OnAsyncComplete(tokenId, pid, seqNum, HandleGenDetails(result));
467         },
468         syncParam);
469 }
470 
IsNeedMetaSync(const StoreMetaData & meta,const std::vector<std::string> & uuids)471 bool RdbServiceImpl::IsNeedMetaSync(const StoreMetaData &meta, const std::vector<std::string> &uuids)
472 {
473     bool isAfterMeta = false;
474     for (const auto &uuid : uuids) {
475         auto metaData = meta;
476         metaData.deviceId = uuid;
477         CapMetaData capMeta;
478         auto capKey = CapMetaRow::GetKeyFor(uuid);
479         if (!MetaDataManager::GetInstance().LoadMeta(std::string(capKey.begin(), capKey.end()), capMeta) ||
480             !MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData)) {
481             isAfterMeta = true;
482             break;
483         }
484         auto [exist, mask] = DeviceMatrix::GetInstance().GetRemoteMask(uuid);
485         if ((mask & DeviceMatrix::META_STORE_MASK) == DeviceMatrix::META_STORE_MASK) {
486             isAfterMeta = true;
487             break;
488         }
489     }
490     return isAfterMeta;
491 }
492 
ProcessResult(const std::map<std::string,int32_t> & results)493 RdbServiceImpl::SyncResult RdbServiceImpl::ProcessResult(const std::map<std::string, int32_t> &results)
494 {
495     std::map<std::string, DBStatus> dbResults;
496     std::vector<std::string> devices;
497     for (const auto &[uuid, status] : results) {
498         dbResults.insert_or_assign(uuid, static_cast<DBStatus>(status));
499         if (static_cast<DBStatus>(status) != DBStatus::OK) {
500             continue;
501         }
502         DeviceMatrix::GetInstance().OnExchanged(uuid, DeviceMatrix::META_STORE_MASK);
503         devices.emplace_back(uuid);
504     }
505     ZLOGD("meta sync finish, total size:%{public}zu, success size:%{public}zu", dbResults.size(), devices.size());
506     return { devices, dbResults };
507 }
508 
DoCompensateSync(const BindEvent & event)509 void RdbServiceImpl::DoCompensateSync(const BindEvent& event)
510 {
511     auto bindInfo = event.GetBindInfo();
512     StoreInfo storeInfo;
513     storeInfo.bundleName = bindInfo.bundleName;
514     storeInfo.tokenId = bindInfo.tokenId;
515     storeInfo.user = bindInfo.user;
516     storeInfo.storeName = bindInfo.storeName;
517     OHOS::NativeRdb::AbsRdbPredicates predicates(bindInfo.tableName);
518     for (auto& [key, value] : bindInfo.primaryKey) {
519         predicates.In(key, std::vector<NativeRdb::ValueObject>({ ValueProxy::Convert(std::move(value)) }));
520     }
521     auto memo = predicates.GetDistributedPredicates();
522     std::shared_ptr<RdbQuery> query = nullptr;
523     if (!memo.tables_.empty()) {
524         query = std::make_shared<RdbQuery>();
525         query->MakeCloudQuery(memo);
526     }
527     auto mixMode = event.GetEventId() == BindEvent::COMPENSATE_SYNC
528                        ? GeneralStore::MixMode(TIME_FIRST, GeneralStore::AUTO_SYNC_MODE)
529                        : GeneralStore::MixMode(CLOUD_FIRST, GeneralStore::AUTO_SYNC_MODE);
530     auto info = ChangeEvent::EventInfo(mixMode, 0, false, query, nullptr);
531     auto evt = std::make_unique<ChangeEvent>(std::move(storeInfo), std::move(info));
532     EventCenter::GetInstance().PostEvent(std::move(evt));
533 }
534 
DoCloudSync(const RdbSyncerParam & param,const RdbService::Option & option,const PredicatesMemo & predicates,const AsyncDetail & async)535 void RdbServiceImpl::DoCloudSync(const RdbSyncerParam &param, const RdbService::Option &option,
536     const PredicatesMemo &predicates, const AsyncDetail &async)
537 {
538     StoreInfo storeInfo;
539     storeInfo.bundleName = param.bundleName_;
540     storeInfo.tokenId = IPCSkeleton::GetCallingTokenID();
541     storeInfo.user = AccountDelegate::GetInstance()->GetUserByToken(storeInfo.tokenId);
542     storeInfo.storeName = RemoveSuffix(param.storeName_);
543     std::shared_ptr<RdbQuery> query = nullptr;
544     if (!predicates.tables_.empty()) {
545         query = std::make_shared<RdbQuery>();
546         query->MakeCloudQuery(predicates);
547     }
548     auto pid = IPCSkeleton::GetCallingPid();
549     GenAsync asyncCallback = [this, tokenId = storeInfo.tokenId, seqNum = option.seqNum, pid](
550                                  const GenDetails &result) mutable {
551         OnAsyncComplete(tokenId, pid, seqNum, HandleGenDetails(result));
552     };
553     GenAsync syncCallback = [async, &param](const GenDetails &details) {
554         ZLOGD("Cloud Sync complete, bundleName:%{public}s, storeName:%{public}s", param.bundleName_.c_str(),
555             Anonymous::Change(param.storeName_).c_str());
556         if (async != nullptr) {
557             async(HandleGenDetails(details));
558         }
559     };
560     auto mixMode = static_cast<int32_t>(GeneralStore::MixMode(option.mode,
561         option.isAutoSync ? GeneralStore::AUTO_SYNC_MODE : GeneralStore::MANUAL_SYNC_MODE));
562     SyncParam syncParam = { mixMode, (option.isAsync ? 0 : WAIT_TIME), option.isCompensation };
563     auto info = ChangeEvent::EventInfo(syncParam, option.isAutoSync, query,
564         option.isAutoSync ? nullptr
565         : option.isAsync  ? asyncCallback
566                           : syncCallback);
567     auto evt = std::make_unique<ChangeEvent>(std::move(storeInfo), std::move(info));
568     EventCenter::GetInstance().PostEvent(std::move(evt));
569 }
570 
Subscribe(const RdbSyncerParam & param,const SubscribeOption & option,RdbStoreObserver * observer)571 int32_t RdbServiceImpl::Subscribe(const RdbSyncerParam &param, const SubscribeOption &option,
572     RdbStoreObserver *observer)
573 {
574     if (option.mode < 0 || option.mode >= SUBSCRIBE_MODE_MAX) {
575         ZLOGE("mode:%{public}d error", option.mode);
576         return RDB_ERROR;
577     }
578     pid_t pid = IPCSkeleton::GetCallingPid();
579     auto tokenId = IPCSkeleton::GetCallingTokenID();
580     bool isCreate = false;
581     syncAgents_.Compute(tokenId, [pid, &param, &isCreate](auto &key, SyncAgents &agents) {
582         auto [it, _] = agents.try_emplace(pid, param.bundleName_);
583         if (it == agents.end()) {
584             return !agents.empty();
585         }
586         if (it->second.watcher_ == nullptr) {
587             isCreate = true;
588             it->second.SetWatcher(std::make_shared<RdbWatcher>());
589         }
590         it->second.count_++;
591         return true;
592     });
593     if (isCreate) {
594         AutoCache::GetInstance().SetObserver(tokenId, RemoveSuffix(param.storeName_),
595             GetWatchers(tokenId, param.storeName_));
596     }
597     return RDB_OK;
598 }
599 
UnSubscribe(const RdbSyncerParam & param,const SubscribeOption & option,RdbStoreObserver * observer)600 int32_t RdbServiceImpl::UnSubscribe(const RdbSyncerParam &param, const SubscribeOption &option,
601     RdbStoreObserver *observer)
602 {
603     if (option.mode < 0 || option.mode >= SUBSCRIBE_MODE_MAX) {
604         ZLOGE("mode:%{public}d error", option.mode);
605         return RDB_ERROR;
606     }
607     bool destroyed = false;
608     auto tokenId = IPCSkeleton::GetCallingTokenID();
609     auto pid = IPCSkeleton::GetCallingPid();
610     syncAgents_.ComputeIfPresent(tokenId, [pid, &destroyed](auto, SyncAgents &agents) {
611         auto it = agents.find(pid);
612         if (it == agents.end()) {
613             return !agents.empty();
614         }
615         it->second.count_--;
616         if (it->second.count_ <= 0) {
617             destroyed = true;
618             it->second.SetWatcher(nullptr);
619         }
620         return true;
621     });
622     if (destroyed) {
623         AutoCache::GetInstance().SetObserver(tokenId, RemoveSuffix(param.storeName_),
624             GetWatchers(tokenId, param.storeName_));
625     }
626     return RDB_OK;
627 }
628 
RegisterAutoSyncCallback(const RdbSyncerParam & param,std::shared_ptr<DetailProgressObserver> observer)629 int32_t RdbServiceImpl::RegisterAutoSyncCallback(const RdbSyncerParam& param,
630     std::shared_ptr<DetailProgressObserver> observer)
631 {
632     pid_t pid = IPCSkeleton::GetCallingPid();
633     auto tokenId = IPCSkeleton::GetCallingTokenID();
634     auto storeName = RemoveSuffix(param.storeName_);
635     syncAgents_.Compute(tokenId, [pid, &param, &storeName](auto, SyncAgents &agents) {
636         auto [it, success] = agents.try_emplace(pid, param.bundleName_);
637         if (it == agents.end()) {
638             return !agents.empty();
639         }
640         if (success) {
641             it->second.callBackStores_.insert(std::make_pair(storeName, 0));
642         }
643         it->second.callBackStores_[storeName]++;
644         return true;
645     });
646     return RDB_OK;
647 }
648 
UnregisterAutoSyncCallback(const RdbSyncerParam & param,std::shared_ptr<DetailProgressObserver> observer)649 int32_t RdbServiceImpl::UnregisterAutoSyncCallback(const RdbSyncerParam& param,
650     std::shared_ptr<DetailProgressObserver> observer)
651 {
652     auto tokenId = IPCSkeleton::GetCallingTokenID();
653     auto pid = IPCSkeleton::GetCallingPid();
654     auto storeName = RemoveSuffix(param.storeName_);
655     syncAgents_.ComputeIfPresent(tokenId, [pid, &storeName](auto, SyncAgents &agents) {
656         auto agent = agents.find(pid);
657         if (agent == agents.end()) {
658             return !agents.empty();
659         }
660         auto it = agent->second.callBackStores_.find(storeName);
661         if (it == agent->second.callBackStores_.end()) {
662             return !agents.empty();
663         }
664         it->second--;
665         if (it->second <= 0) {
666             agent->second.callBackStores_.erase(it);
667         }
668         return !agents.empty();
669     });
670     return RDB_OK;
671 }
672 
Delete(const RdbSyncerParam & param)673 int32_t RdbServiceImpl::Delete(const RdbSyncerParam &param)
674 {
675     XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY);
676     auto tokenId = IPCSkeleton::GetCallingTokenID();
677     AutoCache::GetInstance().CloseStore(tokenId, RemoveSuffix(param.storeName_));
678     RdbSyncerParam tmpParam = param;
679     HapTokenInfo hapTokenInfo;
680     AccessTokenKit::GetHapTokenInfo(tokenId, hapTokenInfo);
681     tmpParam.bundleName_ = hapTokenInfo.bundleName;
682     auto storeMeta = GetStoreMetaData(tmpParam);
683     MetaDataManager::GetInstance().DelMeta(storeMeta.GetKey());
684     MetaDataManager::GetInstance().DelMeta(storeMeta.GetKey(), true);
685     MetaDataManager::GetInstance().DelMeta(storeMeta.GetKeyLocal(), true);
686     MetaDataManager::GetInstance().DelMeta(storeMeta.GetSecretKey(), true);
687     MetaDataManager::GetInstance().DelMeta(storeMeta.GetStrategyKey());
688     MetaDataManager::GetInstance().DelMeta(storeMeta.GetBackupSecretKey(), true);
689     MetaDataManager::GetInstance().DelMeta(storeMeta.GetAutoLaunchKey(), true);
690     MetaDataManager::GetInstance().DelMeta(storeMeta.GetDebugInfoKey(), true);
691     return RDB_OK;
692 }
693 
QuerySharingResource(const RdbSyncerParam & param,const PredicatesMemo & predicates,const std::vector<std::string> & columns)694 std::pair<int32_t, std::shared_ptr<RdbService::ResultSet>> RdbServiceImpl::QuerySharingResource(
695     const RdbSyncerParam& param, const PredicatesMemo& predicates, const std::vector<std::string>& columns)
696 {
697     if (!CheckAccess(param.bundleName_, param.storeName_) ||
698         !TokenIdKit::IsSystemAppByFullTokenID(IPCSkeleton::GetCallingFullTokenID())) {
699         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
700             Anonymous::Change(param.storeName_).c_str());
701         return { RDB_ERROR, {} };
702     }
703     if (predicates.tables_.empty()) {
704         ZLOGE("tables is empty, bundleName:%{public}s, storeName:%{public}s", param.bundleName_.c_str(),
705             Anonymous::Change(param.storeName_).c_str());
706         return { RDB_ERROR, {} };
707     }
708     auto rdbQuery = std::make_shared<RdbQuery>();
709     rdbQuery->MakeQuery(predicates);
710     rdbQuery->SetColumns(columns);
711     StoreInfo storeInfo;
712     storeInfo.bundleName = param.bundleName_;
713     storeInfo.tokenId = IPCSkeleton::GetCallingTokenID();
714     storeInfo.user = AccountDelegate::GetInstance()->GetUserByToken(storeInfo.tokenId);
715     storeInfo.storeName = RemoveSuffix(param.storeName_);
716     auto [status, cursor] = AllocResource(storeInfo, rdbQuery);
717     if (cursor == nullptr) {
718         ZLOGE("cursor is null, bundleName:%{public}s, storeName:%{public}s", param.bundleName_.c_str(),
719             Anonymous::Change(param.storeName_).c_str());
720         return { RDB_ERROR, {} };
721     }
722     return { RDB_OK, std::make_shared<RdbResultSetImpl>(cursor) };
723 }
724 
AllocResource(StoreInfo & storeInfo,std::shared_ptr<RdbQuery> rdbQuery)725 std::pair<int32_t, std::shared_ptr<Cursor>> RdbServiceImpl::AllocResource(StoreInfo& storeInfo,
726     std::shared_ptr<RdbQuery> rdbQuery)
727 {
728     std::pair<int32_t, std::shared_ptr<Cursor>> result;
729     CloudShareEvent::Callback asyncCallback = [&result](int32_t status, std::shared_ptr<Cursor> cursor) {
730         result.first = status;
731         result.second = cursor;
732     };
733     auto evt = std::make_unique<CloudShareEvent>(std::move(storeInfo), rdbQuery, asyncCallback);
734     EventCenter::GetInstance().PostEvent(std::move(evt));
735     return result;
736 }
737 
BeforeOpen(RdbSyncerParam & param)738 int32_t RdbServiceImpl::BeforeOpen(RdbSyncerParam &param)
739 {
740     XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY);
741     auto meta = GetStoreMetaData(param);
742     auto isCreated =
743         MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true);
744     if (!isCreated) {
745         return RDB_OK;
746     }
747     SetReturnParam(meta, param);
748     return RDB_OK;
749 }
750 
SetReturnParam(StoreMetaData & metadata,RdbSyncerParam & param)751 void RdbServiceImpl::SetReturnParam(StoreMetaData &metadata, RdbSyncerParam &param)
752 {
753     param.bundleName_ = metadata.bundleName;
754     param.type_ = metadata.storeType;
755     param.level_ = metadata.securityLevel;
756     param.area_ = metadata.area;
757     param.hapName_ = metadata.hapName;
758     param.customDir_ = metadata.customDir;
759     param.isEncrypt_ = metadata.isEncrypt;
760     param.isAutoClean_ = !metadata.isManualClean;
761     param.isSearchable_ = metadata.isSearchable;
762     param.haMode_ = metadata.haMode;
763 }
764 
AfterOpen(const RdbSyncerParam & param)765 int32_t RdbServiceImpl::AfterOpen(const RdbSyncerParam &param)
766 {
767     XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY);
768     if (!CheckAccess(param.bundleName_, param.storeName_)) {
769         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
770             Anonymous::Change(param.storeName_).c_str());
771         return RDB_ERROR;
772     }
773     auto meta = GetStoreMetaData(param);
774     StoreMetaData old;
775     auto isCreated = MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), old, true);
776     if (!isCreated || meta != old) {
777         Upgrade(param, old);
778         ZLOGD("meta bundle:%{public}s store:%{public}s type:%{public}d->%{public}d encrypt:%{public}d->%{public}d "
779               "area:%{public}d->%{public}d",
780             meta.bundleName.c_str(), meta.GetStoreAlias().c_str(), old.storeType, meta.storeType,
781             old.isEncrypt, meta.isEncrypt, old.area, meta.area);
782         MetaDataManager::GetInstance().SaveMeta(meta.GetKey(), meta, true);
783         AutoLaunchMetaData launchData;
784         if (!MetaDataManager::GetInstance().LoadMeta(meta.GetAutoLaunchKey(), launchData, true)) {
785             RemoteChangeEvent::DataInfo info;
786             info.bundleName = meta.bundleName;
787             info.deviceId = meta.deviceId;
788             info.userId = meta.user;
789             auto evt = std::make_unique<RemoteChangeEvent>(RemoteChangeEvent::RDB_META_SAVE, std::move(info));
790             EventCenter::GetInstance().PostEvent(std::move(evt));
791         }
792     }
793 
794     SaveDebugInfo(meta, param);
795 
796     AppIDMetaData appIdMeta;
797     appIdMeta.bundleName = meta.bundleName;
798     appIdMeta.appId = meta.appId;
799     if (!MetaDataManager::GetInstance().SaveMeta(appIdMeta.GetKey(), appIdMeta, true)) {
800         ZLOGE("meta bundle:%{public}s store:%{public}s type:%{public}d->%{public}d encrypt:%{public}d->%{public}d "
801               "area:%{public}d->%{public}d",
802             meta.bundleName.c_str(), meta.GetStoreAlias().c_str(), old.storeType, meta.storeType,
803             old.isEncrypt, meta.isEncrypt, old.area, meta.area);
804         return RDB_ERROR;
805     }
806     if (param.isEncrypt_ && !param.password_.empty()) {
807         auto ret = SetSecretKey(param, meta);
808         if (ret != RDB_OK) {
809             ZLOGE("Set secret key failed, bundle:%{public}s store:%{public}s",
810                   meta.bundleName.c_str(), meta.GetStoreAlias().c_str());
811             return RDB_ERROR;
812         }
813     }
814     GetCloudSchema(param);
815     return RDB_OK;
816 }
817 
GetCloudSchema(const RdbSyncerParam & param)818 void RdbServiceImpl::GetCloudSchema(const RdbSyncerParam &param)
819 {
820     if (executors_ != nullptr) {
821         StoreInfo storeInfo;
822         storeInfo.tokenId = IPCSkeleton::GetCallingTokenID();
823         storeInfo.bundleName = param.bundleName_;
824         storeInfo.storeName = RemoveSuffix(param.storeName_);
825         auto [instanceId,  user]= GetInstIndexAndUser(storeInfo.tokenId, param.bundleName_);
826         storeInfo.instanceId = instanceId;
827         storeInfo.user = user;
828         storeInfo.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
829         executors_->Execute([storeInfo]() {
830             auto event = std::make_unique<CloudEvent>(CloudEvent::GET_SCHEMA, std::move(storeInfo));
831             EventCenter::GetInstance().PostEvent(move(event));
832             return;
833         });
834     }
835 }
836 
GetStoreMetaData(const RdbSyncerParam & param)837 StoreMetaData RdbServiceImpl::GetStoreMetaData(const RdbSyncerParam &param)
838 {
839     StoreMetaData metaData;
840     metaData.uid = IPCSkeleton::GetCallingUid();
841     metaData.tokenId = IPCSkeleton::GetCallingTokenID();
842     auto [instanceId, user] = GetInstIndexAndUser(metaData.tokenId, param.bundleName_);
843     metaData.instanceId = instanceId;
844     metaData.bundleName = param.bundleName_;
845     metaData.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
846     metaData.storeId = RemoveSuffix(param.storeName_);
847     metaData.user = std::to_string(user);
848     metaData.storeType = param.type_;
849     metaData.securityLevel = param.level_;
850     metaData.area = param.area_;
851     metaData.appId = CheckerManager::GetInstance().GetAppId(Converter::ConvertToStoreInfo(metaData));
852     metaData.appType = "harmony";
853     metaData.hapName = param.hapName_;
854     metaData.customDir = param.customDir_;
855     metaData.dataDir = DirectoryManager::GetInstance().GetStorePath(metaData) + "/" + param.storeName_;
856     metaData.account = AccountDelegate::GetInstance()->GetCurrentAccountId();
857     metaData.isEncrypt = param.isEncrypt_;
858     metaData.isManualClean = !param.isAutoClean_;
859     metaData.isSearchable = param.isSearchable_;
860     metaData.haMode = param.haMode_;
861     return metaData;
862 }
863 
SetSecretKey(const RdbSyncerParam & param,const StoreMetaData & meta)864 int32_t RdbServiceImpl::SetSecretKey(const RdbSyncerParam &param, const StoreMetaData &meta)
865 {
866     SecretKeyMetaData newSecretKey;
867     newSecretKey.storeType = meta.storeType;
868     newSecretKey.sKey = CryptoManager::GetInstance().Encrypt(param.password_);
869     if (newSecretKey.sKey.empty()) {
870         ZLOGE("encrypt work key error.");
871         return RDB_ERROR;
872     }
873     auto time = system_clock::to_time_t(system_clock::now());
874     newSecretKey.time = { reinterpret_cast<uint8_t *>(&time), reinterpret_cast<uint8_t *>(&time) + sizeof(time) };
875     return MetaDataManager::GetInstance().SaveMeta(meta.GetSecretKey(), newSecretKey, true) ? RDB_OK : RDB_ERROR;
876 }
877 
Upgrade(const RdbSyncerParam & param,const StoreMetaData & old)878 int32_t RdbServiceImpl::Upgrade(const RdbSyncerParam &param, const StoreMetaData &old)
879 {
880     if (old.storeType == RDB_DEVICE_COLLABORATION && old.version < StoreMetaData::UUID_CHANGED_TAG) {
881         auto store = GetStore(param);
882         if (store == nullptr) {
883             ZLOGE("store is null, bundleName:%{public}s storeName:%{public}s", param.bundleName_.c_str(),
884                 Anonymous::Change(param.storeName_).c_str());
885             return RDB_ERROR;
886         }
887         return store->Clean({}, GeneralStore::CleanMode::NEARBY_DATA, "") == GeneralError::E_OK ? RDB_OK : RDB_ERROR;
888     }
889     return RDB_OK;
890 }
891 
HandleGenDetails(const GenDetails & details)892 Details RdbServiceImpl::HandleGenDetails(const GenDetails &details)
893 {
894     Details dbDetails;
895     for (const auto& [id, detail] : details) {
896         auto &dbDetail = dbDetails[id];
897         dbDetail.progress = detail.progress;
898         dbDetail.code = detail.code;
899         for (auto &[name, table] : detail.details) {
900             auto &dbTable = dbDetail.details[name];
901             Constant::Copy(&dbTable, &table);
902         }
903     }
904     return dbDetails;
905 }
906 
GetDBPassword(const StoreMetaData & metaData,DistributedDB::CipherPassword & password)907 bool RdbServiceImpl::GetDBPassword(const StoreMetaData &metaData, DistributedDB::CipherPassword &password)
908 {
909     if (!metaData.isEncrypt) {
910         return true;
911     }
912 
913     std::string key = metaData.GetSecretKey();
914     DistributedData::SecretKeyMetaData secretKeyMeta;
915     MetaDataManager::GetInstance().LoadMeta(key, secretKeyMeta, true);
916     std::vector<uint8_t> decryptKey;
917     CryptoManager::GetInstance().Decrypt(secretKeyMeta.sKey, decryptKey);
918     if (password.SetValue(decryptKey.data(), decryptKey.size()) != DistributedDB::CipherPassword::OK) {
919         std::fill(decryptKey.begin(), decryptKey.end(), 0);
920         ZLOGE("Set secret key value failed. len is (%{public}d)", int32_t(decryptKey.size()));
921         return false;
922     }
923     std::fill(decryptKey.begin(), decryptKey.end(), 0);
924     return true;
925 }
926 
RemoveSuffix(const std::string & name)927 std::string RdbServiceImpl::RemoveSuffix(const std::string& name)
928 {
929     std::string suffix(".db");
930     auto pos = name.rfind(suffix);
931     if (pos == std::string::npos || pos < name.length() - suffix.length()) {
932         return name;
933     }
934     return std::string(name, 0, pos);
935 }
936 
GetInstIndexAndUser(uint32_t tokenId,const std::string & bundleName)937 std::pair<int32_t, int32_t> RdbServiceImpl::GetInstIndexAndUser(uint32_t tokenId, const std::string &bundleName)
938 {
939     if (AccessTokenKit::GetTokenTypeFlag(tokenId) != TOKEN_HAP) {
940         return { 0, 0 };
941     }
942 
943     HapTokenInfo tokenInfo;
944     tokenInfo.instIndex = -1;
945     int errCode = AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo);
946     if (errCode != RET_SUCCESS) {
947         ZLOGE("GetHapTokenInfo error:%{public}d, tokenId:0x%{public}x appId:%{public}s", errCode, tokenId,
948             bundleName.c_str());
949         return { -1, -1 };
950     }
951     return { tokenInfo.instIndex, tokenInfo.userID };
952 }
953 
OnBind(const BindInfo & bindInfo)954 int32_t RdbServiceImpl::OnBind(const BindInfo &bindInfo)
955 {
956     executors_ = bindInfo.executors;
957     return 0;
958 }
959 
SetNotifier(sptr<RdbNotifierProxy> notifier)960 void RdbServiceImpl::SyncAgent::SetNotifier(sptr<RdbNotifierProxy> notifier)
961 {
962     notifier_ = notifier;
963     if (watcher_ != nullptr) {
964         watcher_->SetNotifier(notifier);
965     }
966 }
967 
SetWatcher(std::shared_ptr<RdbWatcher> watcher)968 void RdbServiceImpl::SyncAgent::SetWatcher(std::shared_ptr<RdbWatcher> watcher)
969 {
970     if (watcher_ != watcher) {
971         watcher_ = watcher;
972         if (watcher_ != nullptr) {
973             watcher_->SetNotifier(notifier_);
974         }
975     }
976 }
977 
SyncAgent(const std::string & bundleName)978 RdbServiceImpl::SyncAgent::SyncAgent(const std::string &bundleName) : bundleName_(bundleName)
979 {
980     notifier_ = nullptr;
981     watcher_ = nullptr;
982     count_ = 0;
983     callBackStores_.clear();
984 }
985 
CloseStore(const std::string & bundleName,int32_t user,int32_t index,int32_t tokenId) const986 int32_t RdbServiceImpl::RdbStatic::CloseStore(const std::string &bundleName, int32_t user, int32_t index,
987     int32_t tokenId) const
988 {
989     if (tokenId != RdbServiceImpl::RdbStatic::INVALID_TOKENID) {
990         AutoCache::GetInstance().CloseStore(tokenId);
991         return E_OK;
992     }
993     std::string prefix = StoreMetaData::GetPrefix(
994         { DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid, std::to_string(user), "default", bundleName });
995     std::vector<StoreMetaData> storeMetaData;
996     if (!MetaDataManager::GetInstance().LoadMeta(prefix, storeMetaData, true)) {
997         ZLOGE("load meta failed! bundleName:%{public}s, user:%{public}d, index:%{public}d",
998             bundleName.c_str(), user, index);
999         return E_ERROR;
1000     }
1001     for (const auto &meta : storeMetaData) {
1002         if (meta.storeType < StoreMetaData::STORE_RELATIONAL_BEGIN ||
1003             meta.storeType > StoreMetaData::STORE_RELATIONAL_END) {
1004             continue;
1005         }
1006         if (meta.instanceId == index && !meta.appId.empty() && !meta.storeId.empty()) {
1007             AutoCache::GetInstance().CloseStore(meta.tokenId);
1008             break;
1009         }
1010     }
1011     return E_OK;
1012 }
1013 
OnAppUninstall(const std::string & bundleName,int32_t user,int32_t index)1014 int32_t RdbServiceImpl::RdbStatic::OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index)
1015 {
1016     return CloseStore(bundleName, user, index);
1017 }
1018 
OnAppUpdate(const std::string & bundleName,int32_t user,int32_t index)1019 int32_t RdbServiceImpl::RdbStatic::OnAppUpdate(const std::string &bundleName, int32_t user, int32_t index)
1020 {
1021     return CloseStore(bundleName, user, index);
1022 }
1023 
OnClearAppStorage(const std::string & bundleName,int32_t user,int32_t index,int32_t tokenId)1024 int32_t RdbServiceImpl::RdbStatic::OnClearAppStorage(const std::string &bundleName, int32_t user, int32_t index,
1025     int32_t tokenId)
1026 {
1027     return CloseStore(bundleName, user, index, tokenId);
1028 }
1029 
RegisterRdbServiceInfo()1030 void RdbServiceImpl::RegisterRdbServiceInfo()
1031 {
1032     DumpManager::Config serviceInfoConfig;
1033     serviceInfoConfig.fullCmd = "--feature-info";
1034     serviceInfoConfig.abbrCmd = "-f";
1035     serviceInfoConfig.dumpName = "FEATURE_INFO";
1036     serviceInfoConfig.dumpCaption = { "| Display all the service statistics" };
1037     DumpManager::GetInstance().AddConfig("FEATURE_INFO", serviceInfoConfig);
1038 }
1039 
RegisterHandler()1040 void RdbServiceImpl::RegisterHandler()
1041 {
1042     Handler handler =
1043         std::bind(&RdbServiceImpl::DumpRdbServiceInfo, this, std::placeholders::_1, std::placeholders::_2);
1044     DumpManager::GetInstance().AddHandler("FEATURE_INFO", uintptr_t(this), handler);
1045 }
DumpRdbServiceInfo(int fd,std::map<std::string,std::vector<std::string>> & params)1046 void RdbServiceImpl::DumpRdbServiceInfo(int fd, std::map<std::string, std::vector<std::string>> &params)
1047 {
1048     (void)params;
1049     std::string info;
1050     dprintf(fd, "-------------------------------------RdbServiceInfo------------------------------\n%s\n",
1051         info.c_str());
1052 }
OnInitialize()1053 int32_t RdbServiceImpl::OnInitialize()
1054 {
1055     RegisterRdbServiceInfo();
1056     RegisterHandler();
1057     return RDB_OK;
1058 }
1059 
~RdbServiceImpl()1060 RdbServiceImpl::~RdbServiceImpl()
1061 {
1062     DumpManager::GetInstance().RemoveHandler("FEATURE_INFO", uintptr_t(this));
1063 }
1064 
NotifyDataChange(const RdbSyncerParam & param,const RdbChangedData & rdbChangedData,const RdbNotifyConfig & rdbNotifyConfig)1065 int32_t RdbServiceImpl::NotifyDataChange(const RdbSyncerParam &param, const RdbChangedData &rdbChangedData,
1066     const RdbNotifyConfig &rdbNotifyConfig)
1067 {
1068     XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY);
1069     if (!CheckAccess(param.bundleName_, param.storeName_)) {
1070         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
1071             Anonymous::Change(param.storeName_).c_str());
1072         return RDB_ERROR;
1073     }
1074     StoreInfo storeInfo;
1075     storeInfo.tokenId = IPCSkeleton::GetCallingTokenID();
1076     storeInfo.bundleName = param.bundleName_;
1077     storeInfo.storeName = RemoveSuffix(param.storeName_);
1078     auto [instanceId,  user]= GetInstIndexAndUser(storeInfo.tokenId, param.bundleName_);
1079     storeInfo.instanceId = instanceId;
1080     storeInfo.user = user;
1081     storeInfo.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
1082 
1083     DataChangeEvent::EventInfo eventInfo;
1084     eventInfo.isFull = rdbNotifyConfig.isFull_;
1085     for (const auto& [key, value] : rdbChangedData.tableData) {
1086         DataChangeEvent::TableChangeProperties tableChangeProperties = {value.isTrackedDataChange};
1087         eventInfo.tableProperties.insert_or_assign(key, std::move(tableChangeProperties));
1088     }
1089 
1090     if (IsPostImmediately(IPCSkeleton::GetCallingPid(), rdbNotifyConfig, storeInfo, eventInfo, param.storeName_)) {
1091         auto evt = std::make_unique<DataChangeEvent>(std::move(storeInfo), std::move(eventInfo));
1092         EventCenter::GetInstance().PostEvent(std::move(evt));
1093     }
1094 
1095     return RDB_OK;
1096 }
1097 
IsPostImmediately(const int32_t callingPid,const RdbNotifyConfig & rdbNotifyConfig,StoreInfo & storeInfo,DataChangeEvent::EventInfo & eventInfo,const std::string & storeName)1098 bool RdbServiceImpl::IsPostImmediately(const int32_t callingPid, const RdbNotifyConfig &rdbNotifyConfig,
1099     StoreInfo &storeInfo, DataChangeEvent::EventInfo &eventInfo, const std::string &storeName)
1100 {
1101     bool postImmediately = false;
1102     heartbeatTaskIds_.Compute(callingPid, [this, &postImmediately, &rdbNotifyConfig, &storeInfo, &eventInfo,
1103         &storeName](const int32_t &key, std::map<std::string, ExecutorPool::TaskId> &tasks) {
1104         auto iter = tasks.find(storeName);
1105         ExecutorPool::TaskId taskId = ExecutorPool::INVALID_TASK_ID;
1106         if (iter != tasks.end()) {
1107             taskId = iter->second;
1108         }
1109         if (rdbNotifyConfig.delay_ == 0) {
1110             if (taskId != ExecutorPool::INVALID_TASK_ID && executors_ != nullptr) {
1111                 executors_->Remove(taskId);
1112             }
1113             postImmediately = true;
1114             tasks.erase(storeName);
1115             return !tasks.empty();
1116         }
1117 
1118         if (executors_ != nullptr) {
1119             auto task = [storeInfoInner = storeInfo, eventInfoInner = eventInfo]() {
1120                 auto evt = std::make_unique<DataChangeEvent>(std::move(storeInfoInner), std::move(eventInfoInner));
1121                 EventCenter::GetInstance().PostEvent(std::move(evt));
1122             };
1123             if (taskId == ExecutorPool::INVALID_TASK_ID) {
1124                 taskId = executors_->Schedule(std::chrono::milliseconds(rdbNotifyConfig.delay_), task);
1125             } else {
1126                 taskId = executors_->Reset(taskId, std::chrono::milliseconds(rdbNotifyConfig.delay_));
1127             }
1128         }
1129         tasks.insert_or_assign(storeName, taskId);
1130         return true;
1131     });
1132     return postImmediately;
1133 }
1134 
SetSearchable(const RdbSyncerParam & param,bool isSearchable)1135 int32_t RdbServiceImpl::SetSearchable(const RdbSyncerParam& param, bool isSearchable)
1136 {
1137     XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY);
1138     if (!CheckAccess(param.bundleName_, param.storeName_)) {
1139         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
1140             Anonymous::Change(param.storeName_).c_str());
1141         return RDB_ERROR;
1142     }
1143     SetSearchableEvent::EventInfo eventInfo;
1144     eventInfo.isSearchable = isSearchable;
1145     return PostSearchEvent(CloudEvent::SET_SEARCHABLE, param, eventInfo);
1146 }
1147 
PostSearchEvent(int32_t evtId,const RdbSyncerParam & param,SetSearchableEvent::EventInfo & eventInfo)1148 int32_t RdbServiceImpl::PostSearchEvent(int32_t evtId, const RdbSyncerParam& param,
1149     SetSearchableEvent::EventInfo &eventInfo)
1150 {
1151     StoreInfo storeInfo;
1152     storeInfo.tokenId = IPCSkeleton::GetCallingTokenID();
1153     storeInfo.bundleName = param.bundleName_;
1154     storeInfo.storeName = RemoveSuffix(param.storeName_);
1155     auto [instanceId,  user]= GetInstIndexAndUser(storeInfo.tokenId, param.bundleName_);
1156     storeInfo.instanceId = instanceId;
1157     storeInfo.user = user;
1158     storeInfo.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
1159 
1160     auto evt = std::make_unique<SetSearchableEvent>(std::move(storeInfo), std::move(eventInfo), evtId);
1161     EventCenter::GetInstance().PostEvent(std::move(evt));
1162     return RDB_OK;
1163 }
1164 
Disable(const RdbSyncerParam & param)1165 int32_t RdbServiceImpl::Disable(const RdbSyncerParam& param)
1166 {
1167     auto tokenId = IPCSkeleton::GetCallingTokenID();
1168     auto storeId = RemoveSuffix(param.storeName_);
1169     AutoCache::GetInstance().Disable(tokenId, storeId);
1170     return RDB_OK;
1171 }
1172 
Enable(const RdbSyncerParam & param)1173 int32_t RdbServiceImpl::Enable(const RdbSyncerParam& param)
1174 {
1175     auto tokenId = IPCSkeleton::GetCallingTokenID();
1176     auto storeId = RemoveSuffix(param.storeName_);
1177     AutoCache::GetInstance().Enable(tokenId, storeId);
1178     return RDB_OK;
1179 }
1180 
GetPassword(const RdbSyncerParam & param,std::vector<uint8_t> & password)1181 int32_t RdbServiceImpl::GetPassword(const RdbSyncerParam &param, std::vector<uint8_t> &password)
1182 {
1183     if (!CheckAccess(param.bundleName_, param.storeName_)) {
1184         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
1185             Anonymous::Change(param.storeName_).c_str());
1186         return RDB_ERROR;
1187     }
1188     auto meta = GetStoreMetaData(param);
1189     SecretKeyMetaData secretKey;
1190     if (!MetaDataManager::GetInstance().LoadMeta(meta.GetSecretKey(), secretKey, true)) {
1191         ZLOGE("bundleName:%{public}s, storeName:%{public}s. no meta", param.bundleName_.c_str(),
1192             Anonymous::Change(param.storeName_).c_str());
1193         return RDB_NO_META;
1194     }
1195 
1196     if (!CryptoManager::GetInstance().Decrypt(secretKey.sKey, password)) {
1197         ZLOGE("bundleName:%{public}s, storeName:%{public}s. decrypt err", param.bundleName_.c_str(),
1198             Anonymous::Change(param.storeName_).c_str());
1199         return RDB_ERROR;
1200     }
1201     return RDB_OK;
1202 }
1203 
GetStoreInfo(const RdbSyncerParam & param)1204 StoreInfo RdbServiceImpl::GetStoreInfo(const RdbSyncerParam &param)
1205 {
1206     StoreInfo storeInfo;
1207     storeInfo.bundleName = param.bundleName_;
1208     storeInfo.tokenId = IPCSkeleton::GetCallingTokenID();
1209     storeInfo.user = AccountDelegate::GetInstance()->GetUserByToken(storeInfo.tokenId);
1210     storeInfo.storeName = RemoveSuffix(param.storeName_);
1211     return storeInfo;
1212 }
1213 
LockCloudContainer(const RdbSyncerParam & param)1214 std::pair<int32_t, uint32_t> RdbServiceImpl::LockCloudContainer(const RdbSyncerParam &param)
1215 {
1216     std::pair<int32_t, uint32_t> result { RDB_ERROR, 0 };
1217     if (!CheckAccess(param.bundleName_, param.storeName_)) {
1218         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
1219               Anonymous::Change(param.storeName_).c_str());
1220         return result;
1221     }
1222 
1223     auto storeInfo = GetStoreInfo(param);
1224 
1225     CloudLockEvent::Callback callback = [&result](int32_t status, uint32_t expiredTime) {
1226         result.first = status;
1227         result.second = expiredTime;
1228     };
1229     auto evt = std::make_unique<CloudLockEvent>(CloudEvent::LOCK_CLOUD_CONTAINER, std::move(storeInfo), callback);
1230     EventCenter::GetInstance().PostEvent(std::move(evt));
1231     return result;
1232 }
1233 
UnlockCloudContainer(const RdbSyncerParam & param)1234 int32_t RdbServiceImpl::UnlockCloudContainer(const RdbSyncerParam &param)
1235 {
1236     int32_t result = RDB_ERROR;
1237     if (!CheckAccess(param.bundleName_, param.storeName_)) {
1238         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
1239               Anonymous::Change(param.storeName_).c_str());
1240         return result;
1241     }
1242 
1243     auto storeInfo = GetStoreInfo(param);
1244 
1245     CloudLockEvent::Callback callback = [&result](int32_t status, uint32_t expiredTime) {
1246         (void)expiredTime;
1247         result = status;
1248     };
1249     auto evt = std::make_unique<CloudLockEvent>(CloudEvent::UNLOCK_CLOUD_CONTAINER, std::move(storeInfo), callback);
1250     EventCenter::GetInstance().PostEvent(std::move(evt));
1251     return result;
1252 }
1253 
GetDebugInfo(const RdbSyncerParam & param,std::map<std::string,RdbDebugInfo> & debugInfo)1254 int32_t RdbServiceImpl::GetDebugInfo(const RdbSyncerParam &param, std::map<std::string, RdbDebugInfo> &debugInfo)
1255 {
1256     if (!CheckAccess(param.bundleName_, param.storeName_)) {
1257         ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
1258             Anonymous::Change(param.storeName_).c_str());
1259         return RDB_ERROR;
1260     }
1261     auto metaData = GetStoreMetaData(param);
1262     auto isCreated = MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData, true);
1263     if (!isCreated) {
1264         ZLOGE("bundleName:%{public}s, storeName:%{public}s. no meta data", param.bundleName_.c_str(),
1265             Anonymous::Change(param.storeName_).c_str());
1266         return RDB_OK;
1267     }
1268     DistributedData::StoreDebugInfo debugMeta;
1269     isCreated = MetaDataManager::GetInstance().LoadMeta(metaData.GetDebugInfoKey(), debugMeta, true);
1270     if (!isCreated) {
1271         return RDB_OK;
1272     }
1273 
1274     for (auto &[name, fileDebug] : debugMeta.fileInfos) {
1275         RdbDebugInfo rdbInfo;
1276         rdbInfo.inode_ = fileDebug.inode;
1277         rdbInfo.size_ = fileDebug.size;
1278         rdbInfo.dev_ = fileDebug.dev;
1279         rdbInfo.mode_ = fileDebug.mode;
1280         rdbInfo.uid_ = fileDebug.uid;
1281         rdbInfo.gid_ = fileDebug.gid;
1282         debugInfo.insert(std::pair{ name, rdbInfo });
1283     }
1284     return RDB_OK;
1285 }
1286 
SaveDebugInfo(const StoreMetaData & metaData,const RdbSyncerParam & param)1287 int32_t RdbServiceImpl::SaveDebugInfo(const StoreMetaData &metaData, const RdbSyncerParam &param)
1288 {
1289     if (param.infos_.empty()) {
1290         return RDB_OK;
1291     }
1292     DistributedData::StoreDebugInfo debugMeta;
1293     for (auto &[name, info] : param.infos_) {
1294         DistributedData::StoreDebugInfo::FileInfo fileInfo;
1295         fileInfo.inode = info.inode_;
1296         fileInfo.size = info.size_;
1297         fileInfo.dev = info.dev_;
1298         fileInfo.mode = info.mode_;
1299         fileInfo.uid = info.uid_;
1300         fileInfo.gid = info.gid_;
1301         debugMeta.fileInfos.insert(std::pair{name, fileInfo});
1302     }
1303     MetaDataManager::GetInstance().SaveMeta(metaData.GetDebugInfoKey(), debugMeta, true);
1304     return RDB_OK;
1305 }
1306 } // namespace OHOS::DistributedRdb