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 #include "accesstoken_kit.h"
18 #include "account/account_delegate.h"
19 #include "checker/checker_manager.h"
20 #include "cloud/cloud_event.h"
21 #include "cloud/change_event.h"
22 #include "communicator/device_manager_adapter.h"
23 #include "crypto_manager.h"
24 #include "directory/directory_manager.h"
25 #include "eventcenter/event_center.h"
26 #include "ipc_skeleton.h"
27 #include "log_print.h"
28 #include "metadata/appid_meta_data.h"
29 #include "metadata/meta_data_manager.h"
30 #include "metadata/store_meta_data.h"
31 #include "rdb_watcher.h"
32 #include "rdb_notifier_proxy.h"
33 #include "rdb_query.h"
34 #include "store/general_store.h"
35 #include "types_export.h"
36 #include "utils/anonymous.h"
37 #include "utils/constant.h"
38 #include "utils/converter.h"
39 #include "cloud/schema_meta.h"
40 #include "rdb_general_store.h"
41 #include "rdb_result_set_impl.h"
42 using OHOS::DistributedKv::AccountDelegate;
43 using OHOS::DistributedData::CheckerManager;
44 using OHOS::DistributedData::MetaDataManager;
45 using OHOS::DistributedData::StoreMetaData;
46 using OHOS::DistributedData::Anonymous;
47 using namespace OHOS::DistributedData;
48 using namespace OHOS::Security::AccessToken;
49 using DistributedDB::RelationalStoreManager;
50 using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter;
51 using system_clock = std::chrono::system_clock;
52
53 constexpr uint32_t ITERATE_TIMES = 10000;
54 namespace OHOS::DistributedRdb {
55 __attribute__((used)) RdbServiceImpl::Factory RdbServiceImpl::factory_;
Factory()56 RdbServiceImpl::Factory::Factory()
57 {
58 FeatureSystem::GetInstance().RegisterCreator(RdbServiceImpl::SERVICE_NAME, [this]() {
59 if (product_ == nullptr) {
60 product_ = std::make_shared<RdbServiceImpl>();
61 }
62 return product_;
63 });
64 AutoCache::GetInstance().RegCreator(RDB_DEVICE_COLLABORATION, [](const StoreMetaData &metaData) -> GeneralStore* {
65 return new (std::nothrow) RdbGeneralStore(metaData);
66 });
67 }
68
~Factory()69 RdbServiceImpl::Factory::~Factory()
70 {
71 }
72
RdbServiceImpl()73 RdbServiceImpl::RdbServiceImpl()
74 {
75 ZLOGI("construct");
76 DistributedDB::RelationalStoreManager::SetAutoLaunchRequestCallback(
77 [this](const std::string& identifier, DistributedDB::AutoLaunchParam ¶m) {
78 return ResolveAutoLaunch(identifier, param);
79 });
80 auto process = [this](const Event &event) {
81 auto &evt = static_cast<const CloudEvent &>(event);
82 auto storeInfo = evt.GetStoreInfo();
83 StoreMetaData meta;
84 meta.storeId = storeInfo.storeName;
85 meta.bundleName = storeInfo.bundleName;
86 meta.user = std::to_string(storeInfo.user);
87 meta.instanceId = storeInfo.instanceId;
88 meta.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
89 if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta)) {
90 ZLOGE("meta empty, bundleName:%{public}s, storeId:%{public}s", meta.bundleName.c_str(),
91 meta.GetStoreAlias().c_str());
92 return;
93 }
94 auto watchers = GetWatchers(meta.tokenId, meta.storeId);
95 auto store = AutoCache::GetInstance().GetStore(meta, watchers);
96 if (store == nullptr) {
97 ZLOGE("store null, storeId:%{public}s", meta.GetStoreAlias().c_str());
98 return;
99 }
100 };
101 EventCenter::GetInstance().Subscribe(CloudEvent::CLOUD_SYNC, process);
102 }
103
ResolveAutoLaunch(const std::string & identifier,DistributedDB::AutoLaunchParam & param)104 int32_t RdbServiceImpl::ResolveAutoLaunch(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m)
105 {
106 std::string identifierHex = TransferStringToHex(identifier);
107 ZLOGI("%{public}.6s", identifierHex.c_str());
108 std::vector<StoreMetaData> entries;
109 auto localId = DmAdapter::GetInstance().GetLocalDevice().uuid;
110 if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ localId }), entries)) {
111 ZLOGE("get meta failed");
112 return false;
113 }
114 ZLOGI("size=%{public}d", static_cast<int32_t>(entries.size()));
115 for (const auto& entry : entries) {
116 if (entry.storeType != RDB_DEVICE_COLLABORATION) {
117 continue;
118 }
119
120 auto aIdentifier = DistributedDB::RelationalStoreManager::GetRelationalStoreIdentifier(
121 entry.user, entry.appId, entry.storeId);
122 ZLOGI("%{public}s %{public}s %{public}s",
123 entry.user.c_str(), entry.appId.c_str(), Anonymous::Change(entry.storeId).c_str());
124 if (aIdentifier != identifier) {
125 continue;
126 }
127 ZLOGI("find identifier %{public}s", Anonymous::Change(entry.storeId).c_str());
128 param.userId = entry.user;
129 param.appId = entry.appId;
130 param.storeId = entry.storeId;
131 param.path = entry.dataDir;
132 param.option.storeObserver = nullptr;
133 param.option.isEncryptedDb = entry.isEncrypt;
134 if (entry.isEncrypt) {
135 param.option.iterateTimes = ITERATE_TIMES;
136 param.option.cipher = DistributedDB::CipherType::AES_256_GCM;
137 GetPassword(entry, param.option.passwd);
138 }
139 AutoCache::GetInstance().GetStore(entry, GetWatchers(entry.tokenId, entry.storeId));
140 return true;
141 }
142 ZLOGE("not find identifier");
143 return false;
144 }
145
OnAppExit(pid_t uid,pid_t pid,uint32_t tokenId,const std::string & bundleName)146 int32_t RdbServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &bundleName)
147 {
148 OnClientDied(pid);
149 return E_OK;
150 }
151
OnClientDied(pid_t pid)152 void RdbServiceImpl::OnClientDied(pid_t pid)
153 {
154 ZLOGI("client dead pid=%{public}d", pid);
155 syncAgents_.EraseIf([pid](auto &key, SyncAgent &agent) { return agent.pid_ == pid; });
156 }
157
CheckAccess(const std::string & bundleName,const std::string & storeName)158 bool RdbServiceImpl::CheckAccess(const std::string& bundleName, const std::string& storeName)
159 {
160 CheckerManager::StoreInfo storeInfo;
161 storeInfo.uid = IPCSkeleton::GetCallingUid();
162 storeInfo.tokenId = IPCSkeleton::GetCallingTokenID();
163 storeInfo.bundleName = bundleName;
164 storeInfo.storeId = RemoveSuffix(storeName);
165 auto [instanceId, user] = GetInstIndexAndUser(storeInfo.tokenId, storeInfo.bundleName);
166 if (instanceId != 0) {
167 return false;
168 }
169 return !CheckerManager::GetInstance().GetAppId(storeInfo).empty();
170 }
171
ObtainDistributedTableName(const std::string & device,const std::string & table)172 std::string RdbServiceImpl::ObtainDistributedTableName(const std::string &device, const std::string &table)
173 {
174 ZLOGI("device=%{public}s table=%{public}s", Anonymous::Change(device).c_str(), table.c_str());
175 auto uuid = DmAdapter::GetInstance().GetUuidByNetworkId(device);
176 if (uuid.empty()) {
177 ZLOGE("get uuid failed");
178 return "";
179 }
180 return DistributedDB::RelationalStoreManager::GetDistributedTableName(uuid, table);
181 }
182
InitNotifier(const RdbSyncerParam & param,const sptr<IRemoteObject> notifier)183 int32_t RdbServiceImpl::InitNotifier(const RdbSyncerParam ¶m, const sptr<IRemoteObject> notifier)
184 {
185 if (!CheckAccess(param.bundleName_, "")) {
186 ZLOGE("permission error");
187 return RDB_ERROR;
188 }
189 if (notifier == nullptr) {
190 ZLOGE("notifier is null");
191 return RDB_ERROR;
192 }
193
194 auto notifierProxy = iface_cast<RdbNotifierProxy>(notifier);
195 pid_t pid = IPCSkeleton::GetCallingPid();
196 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
197 syncAgents_.Compute(tokenId, [¶m, notifierProxy, pid](auto, SyncAgent &agent) {
198 if (pid != agent.pid_) {
199 agent.ReInit(pid, param.bundleName_);
200 }
201 agent.SetNotifier(notifierProxy);
202 return true;
203 });
204 ZLOGI("success tokenId:%{public}x, pid=%{public}d", tokenId, pid);
205
206 return RDB_OK;
207 }
208
GetStore(const RdbSyncerParam & param)209 std::shared_ptr<DistributedData::GeneralStore> RdbServiceImpl::GetStore(const RdbSyncerParam ¶m)
210 {
211 StoreMetaData storeMetaData = GetStoreMetaData(param);
212 MetaDataManager::GetInstance().LoadMeta(storeMetaData.GetKey(), storeMetaData);
213 auto watchers = GetWatchers(storeMetaData.tokenId, storeMetaData.storeId);
214 auto store = AutoCache::GetInstance().GetStore(storeMetaData, watchers);
215 if (store == nullptr) {
216 ZLOGE("store null, storeId:%{public}s", storeMetaData.GetStoreAlias().c_str());
217 }
218 return store;
219 }
220
SetDistributedTables(const RdbSyncerParam & param,const std::vector<std::string> & tables,int32_t type)221 int32_t RdbServiceImpl::SetDistributedTables(const RdbSyncerParam ¶m, const std::vector<std::string> &tables,
222 int32_t type)
223 {
224 if (!CheckAccess(param.bundleName_, param.storeName_)) {
225 ZLOGE("bundleName:%{public}s, storeName:%{public}s. Permission error", param.bundleName_.c_str(),
226 Anonymous::Change(param.storeName_).c_str());
227 return RDB_ERROR;
228 }
229 auto store = GetStore(param);
230 if (store == nullptr) {
231 ZLOGE("bundleName:%{public}s, storeName:%{public}s. GetStore failed", param.bundleName_.c_str(),
232 Anonymous::Change(param.storeName_).c_str());
233 return RDB_ERROR;
234 }
235 return store->SetDistributedTables(tables, type);
236 }
237
OnAsyncComplete(uint32_t tokenId,uint32_t seqNum,Details && result)238 void RdbServiceImpl::OnAsyncComplete(uint32_t tokenId, uint32_t seqNum, Details &&result)
239 {
240 ZLOGI("tokenId=%{public}x seqnum=%{public}u", tokenId, seqNum);
241 auto [success, agent] = syncAgents_.Find(tokenId);
242 if (success && agent.notifier_ != nullptr) {
243 agent.notifier_->OnComplete(seqNum, std::move(result));
244 }
245 }
246
TransferStringToHex(const std::string & origStr)247 std::string RdbServiceImpl::TransferStringToHex(const std::string &origStr)
248 {
249 if (origStr.empty()) {
250 return "";
251 }
252 const char *hex = "0123456789abcdef";
253 std::string tmp;
254 for (auto item : origStr) {
255 auto currentByte = static_cast<uint8_t>(item);
256 tmp.push_back(hex[currentByte >> 4]); // high 4 bit to one hex.
257 tmp.push_back(hex[currentByte & 0x0F]); // low 4 bit to one hex.
258 }
259 return tmp;
260 }
261
GetWatchers(uint32_t tokenId,const std::string & storeName)262 AutoCache::Watchers RdbServiceImpl::GetWatchers(uint32_t tokenId, const std::string &storeName)
263 {
264 auto [success, agent] = syncAgents_.Find(tokenId);
265 if (agent.watcher_ == nullptr) {
266 return {};
267 }
268 return { agent.watcher_ };
269 }
270
RemoteQuery(const RdbSyncerParam & param,const std::string & device,const std::string & sql,const std::vector<std::string> & selectionArgs,sptr<IRemoteObject> & resultSet)271 int32_t RdbServiceImpl::RemoteQuery(const RdbSyncerParam& param, const std::string& device, const std::string& sql,
272 const std::vector<std::string>& selectionArgs, sptr<IRemoteObject>& resultSet)
273 {
274 if (!CheckAccess(param.bundleName_, param.storeName_)) {
275 ZLOGE("permission error");
276 return RDB_ERROR;
277 }
278 auto store = GetStore(param);
279 if (store == nullptr) {
280 ZLOGE("store is null");
281 return RDB_ERROR;
282 }
283 auto values = ValueProxy::Convert(selectionArgs);
284 RdbQuery rdbQuery(true);
285 rdbQuery.SetDevices({ device });
286 rdbQuery.SetSql(sql, std::move(values));
287 auto cursor = store->Query("", rdbQuery);
288 if (cursor == nullptr) {
289 ZLOGE("Query failed, cursor is null");
290 return RDB_ERROR;
291 }
292 resultSet = new (std::nothrow) RdbResultSetImpl(cursor);
293 if (resultSet == nullptr) {
294 ZLOGE("new resultSet failed");
295 return RDB_ERROR;
296 }
297 return RDB_OK;
298 }
299
Sync(const RdbSyncerParam & param,const Option & option,const PredicatesMemo & predicates,const AsyncDetail & async)300 int32_t RdbServiceImpl::Sync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates,
301 const AsyncDetail &async)
302 {
303 if (!CheckAccess(param.bundleName_, param.storeName_)) {
304 ZLOGE("permission error");
305 return RDB_ERROR;
306 }
307 if (option.mode < DistributedData::GeneralStore::CLOUD_END &&
308 option.mode >= DistributedData::GeneralStore::CLOUD_BEGIN) {
309 DoCloudSync(param, option, predicates, async);
310 return RDB_OK;
311 }
312 return DoSync(param, option, predicates, async);
313 }
314
DoSync(const RdbSyncerParam & param,const RdbService::Option & option,const PredicatesMemo & predicates,const AsyncDetail & async)315 int RdbServiceImpl::DoSync(const RdbSyncerParam ¶m, const RdbService::Option &option,
316 const PredicatesMemo &predicates, const AsyncDetail &async)
317 {
318 auto store = GetStore(param);
319 if (store == nullptr) {
320 return RDB_ERROR;
321 }
322 RdbQuery rdbQuery;
323 rdbQuery.MakeQuery(predicates);
324 if (!option.isAsync) {
325 Details details = {};
326 auto status = store->Sync(
327 DmAdapter::ToUUID(DmAdapter::GetInstance().GetRemoteDevices()), option.mode, rdbQuery,
328 [&details, ¶m](const GenDetails &result) mutable {
329 ZLOGD("Sync complete, bundleName:%{public}s, storeName:%{public}s", param.bundleName_.c_str(),
330 Anonymous::Change(param.storeName_).c_str());
331 details = HandleGenDetails(result);
332 },
333 true);
334 if (async != nullptr) {
335 async(std::move(details));
336 }
337 return status;
338 }
339 ZLOGD("seqNum=%{public}u", option.seqNum);
340 auto tokenId = IPCSkeleton::GetCallingTokenID();
341 return store->Sync(
342 DmAdapter::ToUUID(DmAdapter::GetInstance().GetRemoteDevices()), option.mode, rdbQuery,
343 [this, tokenId, seqNum = option.seqNum](const GenDetails &result) mutable {
344 OnAsyncComplete(tokenId, seqNum, HandleGenDetails(result));
345 },
346 false);
347 }
348
DoCloudSync(const RdbSyncerParam & param,const RdbService::Option & option,const PredicatesMemo & predicates,const AsyncDetail & async)349 void RdbServiceImpl::DoCloudSync(const RdbSyncerParam ¶m, const RdbService::Option &option,
350 const PredicatesMemo &predicates, const AsyncDetail &async)
351 {
352 CloudEvent::StoreInfo storeInfo;
353 storeInfo.bundleName = param.bundleName_;
354 storeInfo.tokenId = IPCSkeleton::GetCallingTokenID();
355 storeInfo.user = AccountDelegate::GetInstance()->GetUserByToken(storeInfo.tokenId);
356 storeInfo.storeName = param.storeName_;
357 std::shared_ptr<RdbQuery> query = nullptr;
358 if (!predicates.tables_.empty()) {
359 query = std::make_shared<RdbQuery>();
360 query->FromTable(predicates.tables_);
361 }
362 GenAsync asyncCallback = [this, tokenId = storeInfo.tokenId, seqNum = option.seqNum](
363 const GenDetails &result) mutable {
364 OnAsyncComplete(tokenId, seqNum, HandleGenDetails(result));
365 };
366 GenAsync syncCallback = [async, ¶m](const GenDetails &details) {
367 ZLOGD("Cloud Sync complete, bundleName:%{public}s, storeName:%{public}s", param.bundleName_.c_str(),
368 Anonymous::Change(param.storeName_).c_str());
369 if (async != nullptr) {
370 async(HandleGenDetails(details));
371 }
372 };
373
374 auto info = ChangeEvent::EventInfo(option.mode, (option.isAsync ? 0 : WAIT_TIME),
375 (option.isAsync && option.seqNum == 0), query, (option.isAsync ? asyncCallback : syncCallback));
376 auto evt = std::make_unique<ChangeEvent>(std::move(storeInfo), std::move(info));
377 EventCenter::GetInstance().PostEvent(std::move(evt));
378 }
379
Subscribe(const RdbSyncerParam & param,const SubscribeOption & option,RdbStoreObserver * observer)380 int32_t RdbServiceImpl::Subscribe(const RdbSyncerParam ¶m, const SubscribeOption &option,
381 RdbStoreObserver *observer)
382 {
383 if (option.mode < 0 || option.mode >= SUBSCRIBE_MODE_MAX) {
384 ZLOGE("mode:%{public}d error", option.mode);
385 return RDB_ERROR;
386 }
387 pid_t pid = IPCSkeleton::GetCallingPid();
388 auto tokenId = IPCSkeleton::GetCallingTokenID();
389 bool isCreate = false;
390 syncAgents_.Compute(tokenId, [pid, ¶m, &isCreate](auto &key, SyncAgent &agent) {
391 if (pid != agent.pid_) {
392 agent.ReInit(pid, param.bundleName_);
393 }
394 if (agent.watcher_ == nullptr) {
395 isCreate = true;
396 agent.SetWatcher(std::make_shared<RdbWatcher>());
397 }
398 agent.count_++;
399 return true;
400 });
401 if (isCreate) {
402 AutoCache::GetInstance().SetObserver(tokenId, param.storeName_, GetWatchers(tokenId, param.storeName_));
403 }
404 return RDB_OK;
405 }
406
UnSubscribe(const RdbSyncerParam & param,const SubscribeOption & option,RdbStoreObserver * observer)407 int32_t RdbServiceImpl::UnSubscribe(const RdbSyncerParam ¶m, const SubscribeOption &option,
408 RdbStoreObserver *observer)
409 {
410 if (option.mode < 0 || option.mode >= SUBSCRIBE_MODE_MAX) {
411 ZLOGE("mode:%{public}d error", option.mode);
412 return RDB_ERROR;
413 }
414 bool destroyed = false;
415 auto tokenId = IPCSkeleton::GetCallingTokenID();
416 syncAgents_.ComputeIfPresent(tokenId, [&destroyed](auto &key, SyncAgent &agent) {
417 if (agent.count_ > 0) {
418 agent.count_--;
419 }
420 if (agent.count_ == 0) {
421 destroyed = true;
422 agent.SetWatcher(nullptr);
423 }
424 return true;
425 });
426 if (destroyed) {
427 AutoCache::GetInstance().SetObserver(tokenId, param.storeName_, GetWatchers(tokenId, param.storeName_));
428 }
429 return RDB_OK;
430 }
431
OnInitialize()432 int32_t RdbServiceImpl::OnInitialize()
433 {
434 return RDB_OK;
435 }
436
Delete(const RdbSyncerParam & param)437 int32_t RdbServiceImpl::Delete(const RdbSyncerParam ¶m)
438 {
439 auto tokenId = IPCSkeleton::GetCallingTokenID();
440 AutoCache::GetInstance().CloseStore(tokenId, param.storeName_);
441 RdbSyncerParam tmpParam = param;
442 HapTokenInfo hapTokenInfo;
443 AccessTokenKit::GetHapTokenInfo(tokenId, hapTokenInfo);
444 tmpParam.bundleName_ = hapTokenInfo.bundleName;
445 auto storeMeta = GetStoreMetaData(tmpParam);
446 MetaDataManager::GetInstance().DelMeta(storeMeta.GetKey());
447 MetaDataManager::GetInstance().DelMeta(storeMeta.GetSecretKey(), true);
448 MetaDataManager::GetInstance().DelMeta(storeMeta.GetStrategyKey());
449 MetaDataManager::GetInstance().DelMeta(storeMeta.GetKeyLocal(), true);
450 return RDB_OK;
451 }
452
GetSchema(const RdbSyncerParam & param)453 int32_t RdbServiceImpl::GetSchema(const RdbSyncerParam ¶m)
454 {
455 if (!CheckAccess(param.bundleName_, param.storeName_)) {
456 ZLOGE("permission error");
457 return RDB_ERROR;
458 }
459 StoreMetaData storeMeta;
460 if (CreateMetaData(param, storeMeta) != RDB_OK) {
461 return RDB_ERROR;
462 }
463
464 if (executors_ != nullptr) {
465 CloudEvent::StoreInfo storeInfo;
466 storeInfo.tokenId = IPCSkeleton::GetCallingTokenID();
467 storeInfo.bundleName = param.bundleName_;
468 storeInfo.storeName = RemoveSuffix(param.storeName_);
469 auto [instanceId, user]= GetInstIndexAndUser(storeInfo.tokenId, param.bundleName_);
470 storeInfo.instanceId = instanceId;
471 storeInfo.user = user;
472 executors_->Execute([storeInfo]() {
473 auto event = std::make_unique<CloudEvent>(CloudEvent::GET_SCHEMA, std::move(storeInfo));
474 EventCenter::GetInstance().PostEvent(move(event));
475 return;
476 });
477 }
478 return RDB_OK;
479 }
480
GetStoreMetaData(const RdbSyncerParam & param)481 StoreMetaData RdbServiceImpl::GetStoreMetaData(const RdbSyncerParam ¶m)
482 {
483 StoreMetaData metaData;
484 metaData.uid = IPCSkeleton::GetCallingUid();
485 metaData.tokenId = IPCSkeleton::GetCallingTokenID();
486 auto [instanceId, user] = GetInstIndexAndUser(metaData.tokenId, param.bundleName_);
487 metaData.instanceId = instanceId;
488 metaData.bundleName = param.bundleName_;
489 metaData.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid;
490 metaData.storeId = RemoveSuffix(param.storeName_);
491 metaData.user = std::to_string(user);
492 metaData.storeType = param.type_;
493 metaData.securityLevel = param.level_;
494 metaData.area = param.area_;
495 metaData.appId = CheckerManager::GetInstance().GetAppId(Converter::ConvertToStoreInfo(metaData));
496 metaData.appType = "harmony";
497 metaData.hapName = param.hapName_;
498 metaData.dataDir = DirectoryManager::GetInstance().GetStorePath(metaData) + "/" + param.storeName_;
499 metaData.account = AccountDelegate::GetInstance()->GetCurrentAccountId();
500 metaData.isEncrypt = param.isEncrypt_;
501 return metaData;
502 }
503
CreateMetaData(const RdbSyncerParam & param,StoreMetaData & old)504 int32_t RdbServiceImpl::CreateMetaData(const RdbSyncerParam ¶m, StoreMetaData &old)
505 {
506 auto meta = GetStoreMetaData(param);
507 bool isCreated = MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), old);
508 if (isCreated && (old.storeType != meta.storeType || Constant::NotEqual(old.isEncrypt, meta.isEncrypt) ||
509 old.area != meta.area)) {
510 ZLOGE("meta bundle:%{public}s store:%{public}s type:%{public}d->%{public}d encrypt:%{public}d->%{public}d "
511 "area:%{public}d->%{public}d",
512 meta.bundleName.c_str(), meta.GetStoreAlias().c_str(), old.storeType, meta.storeType,
513 old.isEncrypt, meta.isEncrypt, old.area, meta.area);
514 return RDB_ERROR;
515 }
516 if (!isCreated || meta != old) {
517 Upgrade(param, old);
518 ZLOGD("meta bundle:%{public}s store:%{public}s type:%{public}d->%{public}d encrypt:%{public}d->%{public}d "
519 "area:%{public}d->%{public}d",
520 meta.bundleName.c_str(), meta.GetStoreAlias().c_str(), old.storeType, meta.storeType,
521 old.isEncrypt, meta.isEncrypt, old.area, meta.area);
522 MetaDataManager::GetInstance().SaveMeta(meta.GetKey(), meta);
523 }
524 AppIDMetaData appIdMeta;
525 appIdMeta.bundleName = meta.bundleName;
526 appIdMeta.appId = meta.appId;
527 if (!MetaDataManager::GetInstance().SaveMeta(appIdMeta.GetKey(), appIdMeta, true)) {
528 ZLOGE("meta bundle:%{public}s store:%{public}s type:%{public}d->%{public}d encrypt:%{public}d->%{public}d "
529 "area:%{public}d->%{public}d",
530 meta.bundleName.c_str(), meta.GetStoreAlias().c_str(), old.storeType, meta.storeType,
531 old.isEncrypt, meta.isEncrypt, old.area, meta.area);
532 return RDB_ERROR;
533 }
534 if (!param.isEncrypt_ || param.password_.empty()) {
535 return RDB_OK;
536 }
537 return SetSecretKey(param, meta);
538 }
539
SetSecretKey(const RdbSyncerParam & param,const StoreMetaData & meta)540 int32_t RdbServiceImpl::SetSecretKey(const RdbSyncerParam ¶m, const StoreMetaData &meta)
541 {
542 SecretKeyMetaData newSecretKey;
543 newSecretKey.storeType = meta.storeType;
544 newSecretKey.sKey = CryptoManager::GetInstance().Encrypt(param.password_);
545 if (newSecretKey.sKey.empty()) {
546 ZLOGE("encrypt work key error.");
547 return RDB_ERROR;
548 }
549 auto time = system_clock::to_time_t(system_clock::now());
550 newSecretKey.time = { reinterpret_cast<uint8_t *>(&time), reinterpret_cast<uint8_t *>(&time) + sizeof(time) };
551 return MetaDataManager::GetInstance().SaveMeta(meta.GetSecretKey(), newSecretKey, true) ? RDB_OK : RDB_ERROR;
552 }
553
Upgrade(const RdbSyncerParam & param,const StoreMetaData & old)554 int32_t RdbServiceImpl::Upgrade(const RdbSyncerParam ¶m, const StoreMetaData &old)
555 {
556 if (old.storeType == RDB_DEVICE_COLLABORATION && old.version < StoreMetaData::UUID_CHANGED_TAG) {
557 auto store = GetStore(param);
558 if (store == nullptr) {
559 ZLOGE("store is null, bundleName:%{public}s storeName:%{public}s", param.bundleName_.c_str(),
560 Anonymous::Change(param.storeName_).c_str());
561 return RDB_ERROR;
562 }
563 return store->Clean({}, GeneralStore::CleanMode::NEARBY_DATA, "") == GeneralError::E_OK ? RDB_OK : RDB_ERROR;
564 }
565 return RDB_OK;
566 }
567
HandleGenDetails(const GenDetails & details)568 Details RdbServiceImpl::HandleGenDetails(const GenDetails &details)
569 {
570 Details dbDetails;
571 for (const auto& [id, detail] : details) {
572 auto &dbDetail = dbDetails[id];
573 dbDetail.progress = detail.progress;
574 dbDetail.code = detail.code;
575 for (auto &[name, table] : detail.details) {
576 auto &dbTable = dbDetail.details[name];
577 Constant::Copy(&dbTable, &table);
578 }
579 }
580 return dbDetails;
581 }
582
GetPassword(const StoreMetaData & metaData,DistributedDB::CipherPassword & password)583 bool RdbServiceImpl::GetPassword(const StoreMetaData &metaData, DistributedDB::CipherPassword &password)
584 {
585 if (!metaData.isEncrypt) {
586 return true;
587 }
588
589 std::string key = metaData.GetSecretKey();
590 DistributedData::SecretKeyMetaData secretKeyMeta;
591 MetaDataManager::GetInstance().LoadMeta(key, secretKeyMeta, true);
592 std::vector<uint8_t> decryptKey;
593 CryptoManager::GetInstance().Decrypt(secretKeyMeta.sKey, decryptKey);
594 if (password.SetValue(decryptKey.data(), decryptKey.size()) != DistributedDB::CipherPassword::OK) {
595 std::fill(decryptKey.begin(), decryptKey.end(), 0);
596 ZLOGE("Set secret key value failed. len is (%{public}d)", int32_t(decryptKey.size()));
597 return false;
598 }
599 std::fill(decryptKey.begin(), decryptKey.end(), 0);
600 return true;
601 }
602
RemoveSuffix(const std::string & name)603 std::string RdbServiceImpl::RemoveSuffix(const std::string& name)
604 {
605 std::string suffix(".db");
606 auto pos = name.rfind(suffix);
607 if (pos == std::string::npos || pos < name.length() - suffix.length()) {
608 return name;
609 }
610 return std::string(name, 0, pos);
611 }
612
GetInstIndexAndUser(uint32_t tokenId,const std::string & bundleName)613 std::pair<int32_t, int32_t> RdbServiceImpl::GetInstIndexAndUser(uint32_t tokenId, const std::string &bundleName)
614 {
615 if (AccessTokenKit::GetTokenTypeFlag(tokenId) != TOKEN_HAP) {
616 return { 0, 0 };
617 }
618
619 HapTokenInfo tokenInfo;
620 tokenInfo.instIndex = -1;
621 int errCode = AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo);
622 if (errCode != RET_SUCCESS) {
623 ZLOGE("GetHapTokenInfo error:%{public}d, tokenId:0x%{public}x appId:%{public}s", errCode, tokenId,
624 bundleName.c_str());
625 return { -1, -1 };
626 }
627 return { tokenInfo.instIndex, tokenInfo.userID };
628 }
629
OnBind(const BindInfo & bindInfo)630 int32_t RdbServiceImpl::OnBind(const BindInfo &bindInfo)
631 {
632 executors_ = bindInfo.executors;
633 return 0;
634 }
635
OnAppUninstall(const std::string & bundleName,int32_t user,int32_t index)636 int32_t RdbServiceImpl::OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index)
637 {
638 return CloseStore(bundleName, user, index);
639 }
640
OnAppUpdate(const std::string & bundleName,int32_t user,int32_t index)641 int32_t RdbServiceImpl::OnAppUpdate(const std::string &bundleName, int32_t user, int32_t index)
642 {
643 return CloseStore(bundleName, user, index);
644 }
645
CloseStore(const std::string & bundleName,int32_t user,int32_t index) const646 int32_t RdbServiceImpl::CloseStore(const std::string &bundleName, int32_t user, int32_t index) const
647 {
648 std::string prefix = StoreMetaData::GetPrefix(
649 { DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid, std::to_string(user), "default", bundleName });
650 std::vector<StoreMetaData> storeMetaData;
651 if (!MetaDataManager::GetInstance().LoadMeta(prefix, storeMetaData)) {
652 ZLOGE("load meta failed! bundleName:%{public}s, user:%{public}d, index:%{public}d",
653 bundleName.c_str(), user, index);
654 return E_ERROR;
655 }
656 for (const auto &meta : storeMetaData) {
657 if (meta.storeType < StoreMetaData::STORE_RELATIONAL_BEGIN ||
658 meta.storeType > StoreMetaData::STORE_RELATIONAL_END) {
659 continue;
660 }
661 if (meta.instanceId == index && !meta.appId.empty() && !meta.storeId.empty()) {
662 AutoCache::GetInstance().CloseStore(meta.tokenId);
663 break;
664 }
665 }
666 return E_OK;
667 }
668
ReInit(pid_t pid,const std::string & bundleName)669 void RdbServiceImpl::SyncAgent::ReInit(pid_t pid, const std::string &bundleName)
670 {
671 pid_ = pid;
672 count_ = 0;
673 bundleName_ = bundleName;
674 notifier_ = nullptr;
675 if (watcher_ != nullptr) {
676 watcher_->SetNotifier(nullptr);
677 }
678 }
679
SetNotifier(sptr<RdbNotifierProxy> notifier)680 void RdbServiceImpl::SyncAgent::SetNotifier(sptr<RdbNotifierProxy> notifier)
681 {
682 notifier_ = notifier;
683 if (watcher_ != nullptr) {
684 watcher_->SetNotifier(notifier);
685 }
686 }
687
SetWatcher(std::shared_ptr<RdbWatcher> watcher)688 void RdbServiceImpl::SyncAgent::SetWatcher(std::shared_ptr<RdbWatcher> watcher)
689 {
690 if (watcher_ != watcher) {
691 watcher_ = watcher;
692 if (watcher_ != nullptr) {
693 watcher_->SetNotifier(notifier_);
694 }
695 }
696 }
697 } // namespace OHOS::DistributedRdb
698