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
16 #define LOG_TAG "UdmfServiceImpl"
17
18 #include "udmf_service_impl.h"
19
20 #include "ipc_skeleton.h"
21 #include "tokenid_kit.h"
22
23 #include "accesstoken_kit.h"
24 #include "bootstrap.h"
25 #include "bundle_info.h"
26 #include "bundlemgr/bundle_mgr_proxy.h"
27 #include "checker_manager.h"
28 #include "device_manager_adapter.h"
29 #include "iservice_registry.h"
30 #include "lifecycle/lifecycle_manager.h"
31 #include "log_print.h"
32 #include "metadata/store_meta_data.h"
33 #include "metadata/meta_data_manager.h"
34 #include "preprocess_utils.h"
35 #include "reporter.h"
36 #include "store_account_observer.h"
37 #include "system_ability_definition.h"
38 #include "uri_permission_manager.h"
39 #include "udmf_radar_reporter.h"
40 #include "unified_data_helper.h"
41 #include "utils/anonymous.h"
42
43 namespace OHOS {
44 namespace UDMF {
45 using namespace Security::AccessToken;
46 using namespace OHOS::DistributedHardware;
47 using FeatureSystem = DistributedData::FeatureSystem;
48 using UdmfBehaviourMsg = OHOS::DistributedDataDfx::UdmfBehaviourMsg;
49 using Reporter = OHOS::DistributedDataDfx::Reporter;
50 using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter;
51 using StoreMetaData = OHOS::DistributedData::StoreMetaData;
52 using namespace RadarReporter;
53 using namespace DistributedKv;
54 constexpr const char *DRAG_AUTHORIZED_PROCESSES[] = {"msdp_sa", "collaboration_service"};
55 constexpr const char *DATA_PREFIX = "udmf://";
56 constexpr const char *FILE_SCHEME = "file";
57 constexpr const char *PRIVILEGE_READ_AND_KEEP = "readAndKeep";
58 constexpr const char *MANAGE_UDMF_APP_SHARE_OPTION = "ohos.permission.MANAGE_UDMF_APP_SHARE_OPTION";
59 constexpr const char *DEVICE_2IN1_TAG = "2in1";
60 constexpr const char *DEVICE_PHONE_TAG = "phone";
61 constexpr const char *DEVICE_DEFAULT_TAG = "default";
62 constexpr const char *HAP_LIST[] = {"com.ohos.pasteboarddialog"};
63 __attribute__((used)) UdmfServiceImpl::Factory UdmfServiceImpl::factory_;
Factory()64 UdmfServiceImpl::Factory::Factory()
65 {
66 ZLOGI("Register udmf creator!");
67 FeatureSystem::GetInstance().RegisterCreator("udmf", [this]() {
68 if (product_ == nullptr) {
69 product_ = std::make_shared<UdmfServiceImpl>();
70 }
71 return product_;
72 }, FeatureSystem::BIND_NOW);
73 auto observer = std::make_shared<RuntimeStoreAccountObserver>();
74 DistributedData::AccountDelegate::GetInstance()->Subscribe(observer);
75 }
76
~Factory()77 UdmfServiceImpl::Factory::~Factory()
78 {
79 product_ = nullptr;
80 }
81
UdmfServiceImpl()82 UdmfServiceImpl::UdmfServiceImpl()
83 {
84 CheckerManager::GetInstance().LoadCheckers();
85 }
86
SetData(CustomOption & option,UnifiedData & unifiedData,std::string & key)87 int32_t UdmfServiceImpl::SetData(CustomOption &option, UnifiedData &unifiedData, std::string &key)
88 {
89 ZLOGD("start");
90 int32_t res = E_OK;
91 UdmfBehaviourMsg msg;
92 std::string types;
93 auto find = UD_INTENTION_MAP.find(option.intention);
94 msg.channel = find == UD_INTENTION_MAP.end() ? "invalid" : find->second;
95 msg.operation = "insert";
96 std::string bundleName;
97 if (!PreProcessUtils::GetHapBundleNameByToken(option.tokenId, bundleName)) {
98 msg.appId = "unknown";
99 res = E_ERROR;
100 } else {
101 msg.appId = bundleName;
102 res = SaveData(option, unifiedData, key);
103 }
104 auto errFind = ERROR_MAP.find(res);
105 msg.result = errFind == ERROR_MAP.end() ? "E_ERROR" : errFind->second;
106
107 for (const auto &record : unifiedData.GetRecords()) {
108 for (const auto &type : record->GetUtdIds()) {
109 types.append("-").append(type);
110 }
111 }
112 msg.dataType = types;
113 msg.dataSize = unifiedData.GetSize();
114 Reporter::GetInstance()->GetBehaviourReporter()->UDMFReport(msg);
115 return res;
116 }
117
SaveData(CustomOption & option,UnifiedData & unifiedData,std::string & key)118 int32_t UdmfServiceImpl::SaveData(CustomOption &option, UnifiedData &unifiedData, std::string &key)
119 {
120 if (!unifiedData.IsValid()) {
121 ZLOGE("UnifiedData is invalid.");
122 return E_INVALID_PARAMETERS;
123 }
124
125 if (!UnifiedDataUtils::IsValidIntention(option.intention)) {
126 ZLOGE("Invalid parameters intention: %{public}d.", option.intention);
127 return E_INVALID_PARAMETERS;
128 }
129
130 // imput runtime info before put it into store and save one privilege
131 if (PreProcessUtils::RuntimeDataImputation(unifiedData, option) != E_OK) {
132 ZLOGE("Imputation failed");
133 return E_ERROR;
134 }
135
136 std::string intention = unifiedData.GetRuntime()->key.intention;
137 if (intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) {
138 int32_t ret = PreProcessUtils::SetRemoteUri(option.tokenId, unifiedData);
139 if (ret != E_OK) {
140 ZLOGE("SetRemoteUri failed, ret: %{public}d, bundleName:%{public}s.", ret,
141 unifiedData.GetRuntime()->createPackage.c_str());
142 return ret;
143 }
144 }
145 PreProcessUtils::SetRecordUid(unifiedData);
146
147 auto store = StoreCache::GetInstance().GetStore(intention);
148 if (store == nullptr) {
149 ZLOGE("Get store failed:%{public}s", intention.c_str());
150 return E_DB_ERROR;
151 }
152
153 if (store->Put(unifiedData) != E_OK) {
154 ZLOGE("Put unified data failed:%{public}s", intention.c_str());
155 return E_DB_ERROR;
156 }
157 key = unifiedData.GetRuntime()->key.GetUnifiedKey();
158 ZLOGD("Put unified data successful, key: %{public}s.", key.c_str());
159 return E_OK;
160 }
161
GetData(const QueryOption & query,UnifiedData & unifiedData)162 int32_t UdmfServiceImpl::GetData(const QueryOption &query, UnifiedData &unifiedData)
163 {
164 ZLOGD("start");
165 int32_t res = E_OK;
166 UdmfBehaviourMsg msg;
167 std::string types;
168 auto find = UD_INTENTION_MAP.find(query.intention);
169 msg.channel = find == UD_INTENTION_MAP.end() ? "invalid" : find->second;
170 msg.operation = "insert";
171 std::string bundleName;
172 if (!PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName)) {
173 msg.appId = "unknown";
174 res = E_ERROR;
175 } else {
176 msg.appId = bundleName;
177 res = RetrieveData(query, unifiedData);
178 }
179 TransferToEntriesIfNeed(query, unifiedData);
180 auto errFind = ERROR_MAP.find(res);
181 msg.result = errFind == ERROR_MAP.end() ? "E_ERROR" : errFind->second;
182 for (const auto &record : unifiedData.GetRecords()) {
183 for (const auto &type : record->GetUtdIds()) {
184 types.append("-").append(type);
185 }
186 }
187 msg.dataType = types;
188 msg.dataSize = unifiedData.GetSize();
189 Reporter::GetInstance()->GetBehaviourReporter()->UDMFReport(msg);
190 return res;
191 }
192
CheckDragParams(UnifiedKey & key,const QueryOption & query)193 bool UdmfServiceImpl::CheckDragParams(UnifiedKey &key, const QueryOption &query)
194 {
195 if (!key.IsValid()) {
196 ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str());
197 return false;
198 }
199 if (key.intention != UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) {
200 ZLOGE("Invalid intention:%{public}s", key.intention.c_str());
201 return false;
202 }
203 return true;
204 }
205
RetrieveData(const QueryOption & query,UnifiedData & unifiedData)206 int32_t UdmfServiceImpl::RetrieveData(const QueryOption &query, UnifiedData &unifiedData)
207 {
208 UnifiedKey key(query.key);
209 if (!CheckDragParams(key, query)) {
210 return E_INVALID_PARAMETERS;
211 }
212 auto store = StoreCache::GetInstance().GetStore(key.intention);
213 if (store == nullptr) {
214 ZLOGE("Get store failed:%{public}s", key.intention.c_str());
215 return E_DB_ERROR;
216 }
217 int32_t res = store->Get(query.key, unifiedData);
218 if (res != E_OK) {
219 ZLOGE("Get data failed,res:%{public}d,key:%{public}s", res, query.key.c_str());
220 return res;
221 }
222
223 if (!unifiedData.IsComplete()) {
224 ZLOGE("Get data incomplete,key:%{public}s", query.key.c_str());
225 return E_NOT_FOUND;
226 }
227
228 CheckerManager::CheckInfo info;
229 info.tokenId = query.tokenId;
230 std::shared_ptr<Runtime> runtime = unifiedData.GetRuntime();
231 if (runtime == nullptr) {
232 return E_DB_ERROR;
233 }
234 if (!CheckerManager::GetInstance().IsValid(runtime->privileges, info) && !IsPermissionInCache(query)) {
235 RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
236 BizScene::GET_DATA, GetDataStage::VERIFY_PRIVILEGE, StageRes::FAILED, E_NO_PERMISSION);
237 return E_NO_PERMISSION;
238 }
239
240 if (key.intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) {
241 int32_t ret = ProcessUri(query, unifiedData);
242 if (ret != E_OK) {
243 RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
244 BizScene::GET_DATA, GetDataStage::GRANT_URI_PERMISSION, StageRes::FAILED, ret);
245 ZLOGE("ProcessUri failed:%{public}d", ret);
246 return E_NO_PERMISSION;
247 }
248 }
249 if (!IsReadAndKeep(runtime->privileges, query)) {
250 if (LifeCycleManager::GetInstance().OnGot(key) != E_OK) {
251 ZLOGE("Remove data failed:%{public}s", key.intention.c_str());
252 return E_DB_ERROR;
253 }
254 }
255
256 privilegeCache_.erase(query.key);
257
258 PreProcessUtils::SetRemoteData(unifiedData);
259 return E_OK;
260 }
261
IsPermissionInCache(const QueryOption & query)262 bool UdmfServiceImpl::IsPermissionInCache(const QueryOption &query)
263 {
264 auto iter = privilegeCache_.find(query.key);
265 if (iter != privilegeCache_.end() && iter->second.tokenId == query.tokenId) {
266 return true;
267 }
268 return false;
269 }
270
IsReadAndKeep(const std::vector<Privilege> & privileges,const QueryOption & query)271 bool UdmfServiceImpl::IsReadAndKeep(const std::vector<Privilege> &privileges, const QueryOption &query)
272 {
273 for (const auto &privilege : privileges) {
274 if (privilege.tokenId == query.tokenId && privilege.readPermission == PRIVILEGE_READ_AND_KEEP) {
275 return true;
276 }
277 }
278
279 auto iter = privilegeCache_.find(query.key);
280 if (iter != privilegeCache_.end() && iter->second.tokenId == query.tokenId &&
281 iter->second.readPermission == PRIVILEGE_READ_AND_KEEP) {
282 return true;
283 }
284 return false;
285 }
286
ProcessUri(const QueryOption & query,UnifiedData & unifiedData)287 int32_t UdmfServiceImpl::ProcessUri(const QueryOption &query, UnifiedData &unifiedData)
288 {
289 std::string localDeviceId = PreProcessUtils::GetLocalDeviceId();
290 std::vector<Uri> allUri;
291 int32_t verifyRes = ProcessCrossDeviceData(query.tokenId, unifiedData, allUri);
292 if (verifyRes != E_OK) {
293 ZLOGE("verify unifieddata fail, key=%{public}s, stauts=%{public}d", query.key.c_str(), verifyRes);
294 return verifyRes;
295 }
296 std::string bundleName;
297 if (!PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName)) {
298 ZLOGE("Get bundleName fail,key=%{public}s,tokenId=%d", query.key.c_str(), query.tokenId);
299 return E_ERROR;
300 }
301 std::string sourceDeviceId = unifiedData.GetRuntime()->deviceId;
302 if (localDeviceId == sourceDeviceId && query.tokenId == unifiedData.GetRuntime()->tokenId) {
303 ZLOGW("No uri permissions needed,queryKey=%{public}s", query.key.c_str());
304 return E_OK;
305 }
306 if (UriPermissionManager::GetInstance().GrantUriPermission(allUri, query.tokenId, query.key) != E_OK) {
307 ZLOGE("GrantUriPermission fail, bundleName=%{public}s, key=%{public}s.",
308 bundleName.c_str(), query.key.c_str());
309 return E_NO_PERMISSION;
310 }
311 return E_OK;
312 }
313
ProcessCrossDeviceData(uint32_t tokenId,UnifiedData & unifiedData,std::vector<Uri> & uris)314 int32_t UdmfServiceImpl::ProcessCrossDeviceData(uint32_t tokenId, UnifiedData &unifiedData, std::vector<Uri> &uris)
315 {
316 if (unifiedData.GetRuntime() == nullptr) {
317 ZLOGE("Get runtime empty!");
318 return E_DB_ERROR;
319 }
320 bool isLocal = PreProcessUtils::GetLocalDeviceId() == unifiedData.GetRuntime()->deviceId;
321 auto records = unifiedData.GetRecords();
322 bool hasError = false;
323 PreProcessUtils::ProcessFileType(records, [&] (std::shared_ptr<Object> obj) {
324 if (hasError) {
325 return false;
326 }
327 std::string oriUri;
328 obj->GetValue(ORI_URI, oriUri);
329 if (oriUri.empty()) {
330 ZLOGW("Get uri is empty.");
331 return false;
332 }
333 Uri uri(oriUri);
334 std::string scheme = uri.GetScheme();
335 std::transform(scheme.begin(), scheme.end(), scheme.begin(), ::tolower);
336 if (!isLocal) {
337 std::string remoteUri;
338 obj->GetValue(REMOTE_URI, remoteUri);
339 if (remoteUri.empty() && scheme == FILE_SCHEME) {
340 ZLOGE("Remote URI required for cross-device");
341 hasError = true;
342 return false;
343 }
344 if (!remoteUri.empty()) {
345 obj->value_.insert_or_assign(ORI_URI, remoteUri); // cross dev, need dis path.
346 uri = Uri(remoteUri);
347 scheme = uri.GetScheme();
348 std::transform(scheme.begin(), scheme.end(), scheme.begin(), ::tolower);
349 }
350 }
351 if (uri.GetAuthority().empty() || scheme != FILE_SCHEME) {
352 ZLOGW("Empty authority or scheme not file");
353 return false;
354 }
355 uris.push_back(uri);
356 return true;
357 });
358 PreProcessUtils::ProcessHtmlFileUris(tokenId, unifiedData, isLocal, uris);
359 return hasError ? E_ERROR : E_OK;
360 }
361
GetBatchData(const QueryOption & query,std::vector<UnifiedData> & unifiedDataSet)362 int32_t UdmfServiceImpl::GetBatchData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet)
363 {
364 ZLOGD("start");
365 std::vector<UnifiedData> dataSet;
366 std::shared_ptr<Store> store;
367 auto status = QueryDataCommon(query, dataSet, store);
368 if (status != E_OK) {
369 ZLOGE("QueryDataCommon failed.");
370 return status;
371 }
372 if (dataSet.empty()) {
373 ZLOGW("DataSet empty,key:%{public}s,intention:%{public}d", query.key.c_str(), query.intention);
374 return E_OK;
375 }
376 for (auto &data : dataSet) {
377 PreProcessUtils::SetRemoteData(data);
378 unifiedDataSet.push_back(data);
379 }
380 return E_OK;
381 }
382
UpdateData(const QueryOption & query,UnifiedData & unifiedData)383 int32_t UdmfServiceImpl::UpdateData(const QueryOption &query, UnifiedData &unifiedData)
384 {
385 UnifiedKey key(query.key);
386 if (!unifiedData.IsValid() || !key.IsValid()) {
387 ZLOGE("data or key is invalid,key=%{public}s", query.key.c_str());
388 return E_INVALID_PARAMETERS;
389 }
390 std::string bundleName;
391 PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName);
392 if (key.bundleName != bundleName && !HasDatahubPriviledge(bundleName)) {
393 ZLOGE("update data failed by %{public}s, key: %{public}s.", bundleName.c_str(), query.key.c_str());
394 return E_INVALID_PARAMETERS;
395 }
396 auto store = StoreCache::GetInstance().GetStore(key.intention);
397 if (store == nullptr) {
398 ZLOGE("Get store failed:%{public}s", key.intention.c_str());
399 return E_DB_ERROR;
400 }
401 UnifiedData data;
402 int32_t res = store->Get(query.key, data);
403 if (res != E_OK) {
404 ZLOGE("Get data failed:%{public}s", key.intention.c_str());
405 return res;
406 }
407 if (data.IsEmpty()) {
408 ZLOGE("Invalid parameter, unified data has no record; intention: %{public}s.", key.intention.c_str());
409 return E_INVALID_PARAMETERS;
410 }
411 std::shared_ptr<Runtime> runtime = data.GetRuntime();
412 if (runtime == nullptr) {
413 return E_DB_ERROR;
414 }
415 if (runtime->tokenId != query.tokenId && !HasDatahubPriviledge(bundleName)) {
416 ZLOGE("Update failed: tokenId mismatch");
417 return E_INVALID_PARAMETERS;
418 }
419 runtime->lastModifiedTime = PreProcessUtils::GetTimestamp();
420 unifiedData.SetRuntime(*runtime);
421 PreProcessUtils::SetRecordUid(unifiedData);
422 if (store->Update(unifiedData) != E_OK) {
423 ZLOGE("Unified data update failed:%{public}s", key.intention.c_str());
424 return E_DB_ERROR;
425 }
426 return E_OK;
427 }
428
DeleteData(const QueryOption & query,std::vector<UnifiedData> & unifiedDataSet)429 int32_t UdmfServiceImpl::DeleteData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet)
430 {
431 ZLOGD("start");
432 std::vector<UnifiedData> dataSet;
433 std::shared_ptr<Store> store;
434 auto status = QueryDataCommon(query, dataSet, store);
435 if (status != E_OK) {
436 ZLOGE("QueryDataCommon failed.");
437 return status;
438 }
439 if (dataSet.empty()) {
440 ZLOGW("DataSet has no data, key: %{public}s, intention: %{public}d.", query.key.c_str(), query.intention);
441 return E_OK;
442 }
443 std::shared_ptr<Runtime> runtime;
444 std::vector<std::string> deleteKeys;
445 for (const auto &data : dataSet) {
446 runtime = data.GetRuntime();
447 if (runtime == nullptr) {
448 return E_DB_ERROR;
449 }
450 if (runtime->tokenId == query.tokenId) {
451 unifiedDataSet.push_back(data);
452 deleteKeys.push_back(UnifiedKey(runtime->key.key).GetPropertyKey());
453 }
454 }
455 if (deleteKeys.empty()) {
456 ZLOGE("No data to delete for this application");
457 return E_OK;
458 }
459 ZLOGI("Delete data start. size: %{public}zu.", deleteKeys.size());
460 if (store->DeleteBatch(deleteKeys) != E_OK) {
461 ZLOGE("Remove data failed.");
462 return E_DB_ERROR;
463 }
464 return E_OK;
465 }
466
GetSummary(const QueryOption & query,Summary & summary)467 int32_t UdmfServiceImpl::GetSummary(const QueryOption &query, Summary &summary)
468 {
469 ZLOGD("start");
470 UnifiedKey key(query.key);
471 if (!key.IsValid()) {
472 ZLOGE("Invalid unified key:%{public}s", query.key.c_str());
473 return E_INVALID_PARAMETERS;
474 }
475
476 auto store = StoreCache::GetInstance().GetStore(key.intention);
477 if (store == nullptr) {
478 ZLOGE("Get store failed:%{public}s", key.intention.c_str());
479 return E_DB_ERROR;
480 }
481
482 if (store->GetSummary(key, summary) != E_OK) {
483 ZLOGE("Store get summary failed:%{public}s", key.intention.c_str());
484 return E_DB_ERROR;
485 }
486 return E_OK;
487 }
488
AddPrivilege(const QueryOption & query,Privilege & privilege)489 int32_t UdmfServiceImpl::AddPrivilege(const QueryOption &query, Privilege &privilege)
490 {
491 ZLOGD("start");
492 UnifiedKey key(query.key);
493 if (!key.IsValid()) {
494 ZLOGE("Invalid unified key:%{public}s", query.key.c_str());
495 return E_INVALID_PARAMETERS;
496 }
497
498 std::string processName;
499 if (!PreProcessUtils::GetNativeProcessNameByToken(query.tokenId, processName)) {
500 return E_ERROR;
501 }
502
503 if (key.intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) {
504 if (find(DRAG_AUTHORIZED_PROCESSES, std::end(DRAG_AUTHORIZED_PROCESSES), processName) ==
505 std::end(DRAG_AUTHORIZED_PROCESSES)) {
506 ZLOGE("Process:%{public}s lacks permission for intention:drag", processName.c_str());
507 return E_NO_PERMISSION;
508 }
509 } else {
510 ZLOGE("Intention: %{public}s has no authorized processes", key.intention.c_str());
511 return E_NO_PERMISSION;
512 }
513
514 auto store = StoreCache::GetInstance().GetStore(key.intention);
515 if (store == nullptr) {
516 ZLOGE("Get store failed:%{public}s", key.intention.c_str());
517 return E_DB_ERROR;
518 }
519
520 Runtime runtime;
521 auto res = store->GetRuntime(query.key, runtime);
522 if (res == E_NOT_FOUND) {
523 privilegeCache_[query.key] = privilege;
524 ZLOGW("Add privilege in cache, key: %{public}s.", query.key.c_str());
525 return E_OK;
526 }
527 if (res != E_OK) {
528 ZLOGE("Get runtime failed, res:%{public}d, key:%{public}s.", res, query.key.c_str());
529 return res;
530 }
531 runtime.privileges.emplace_back(privilege);
532 res = store->PutRuntime(query.key, runtime);
533 if (res != E_OK) {
534 ZLOGE("Update runtime failed, res:%{public}d, key:%{public}s", res, query.key.c_str());
535 }
536 return res;
537 }
538
Sync(const QueryOption & query,const std::vector<std::string> & devices)539 int32_t UdmfServiceImpl::Sync(const QueryOption &query, const std::vector<std::string> &devices)
540 {
541 ZLOGD("start");
542 RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__),
543 BizScene::SYNC_DATA, SyncDataStage::SYNC_BEGIN, StageRes::IDLE, BizState::DFX_BEGIN);
544 UnifiedKey key(query.key);
545 if (!key.IsValid()) {
546 RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
547 BizScene::SYNC_DATA, SyncDataStage::SYNC_BEGIN, StageRes::FAILED, E_INVALID_PARAMETERS, BizState::DFX_END);
548 ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str());
549 return E_INVALID_PARAMETERS;
550 }
551 RegisterAsyncProcessInfo(query.key);
552 auto store = StoreCache::GetInstance().GetStore(key.intention);
553 if (store == nullptr) {
554 RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
555 BizScene::SYNC_DATA, SyncDataStage::SYNC_BEGIN, StageRes::FAILED, E_DB_ERROR, BizState::DFX_END);
556 ZLOGE("Get store failed:%{public}s", key.intention.c_str());
557 return E_DB_ERROR;
558 }
559 auto callback = [this, query](AsyncProcessInfo &syncInfo) {
560 if (query.key.empty()) {
561 return;
562 }
563 syncInfo.businessUdKey = query.key;
564 std::lock_guard<std::mutex> lock(mutex_);
565 asyncProcessInfoMap_.insert_or_assign(syncInfo.businessUdKey, syncInfo);
566 ZLOGD("store.Sync: name=%{public}s, id=%{public}u, status=%{public}u, total=%{public}u, finish=%{public}u",
567 syncInfo.srcDevName.c_str(), syncInfo.syncId, syncInfo.syncStatus,
568 syncInfo.syncTotal, syncInfo.syncFinished);
569 };
570 RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__),
571 BizScene::SYNC_DATA, SyncDataStage::SYNC_BEGIN, StageRes::SUCCESS);
572 if (store->Sync(devices, callback) != E_OK) {
573 ZLOGE("Store sync failed:%{public}s", key.intention.c_str());
574 RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
575 BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::FAILED, E_DB_ERROR, BizState::DFX_END);
576 return E_DB_ERROR;
577 }
578 return E_OK;
579 }
580
IsRemoteData(const QueryOption & query,bool & result)581 int32_t UdmfServiceImpl::IsRemoteData(const QueryOption &query, bool &result)
582 {
583 UnifiedKey key(query.key);
584 if (!key.IsValid()) {
585 ZLOGE("Invalid unified key:%{public}s", query.key.c_str());
586 return E_INVALID_PARAMETERS;
587 }
588
589 auto store = StoreCache::GetInstance().GetStore(key.intention);
590 if (store == nullptr) {
591 ZLOGE("Get store failed:%{public}s", key.intention.c_str());
592 return E_DB_ERROR;
593 }
594
595 Runtime runtime;
596 auto res = store->GetRuntime(query.key, runtime);
597 if (res != E_OK) {
598 ZLOGE("Get runtime failed, res:%{public}d, key:%{public}s.", res, query.key.c_str());
599 return E_DB_ERROR;
600 }
601
602 std::string localDeviceId = PreProcessUtils::GetLocalDeviceId();
603 if (localDeviceId != runtime.deviceId) {
604 result = true;
605 }
606 return E_OK;
607 }
608
SetAppShareOption(const std::string & intention,int32_t shareOption)609 int32_t UdmfServiceImpl::SetAppShareOption(const std::string &intention, int32_t shareOption)
610 {
611 if (intention.empty() || shareOption >= SHARE_OPTIONS_BUTT || shareOption < IN_APP) {
612 ZLOGE("para is invalid,intention:%{public}s,shareOption:%{public}d",
613 intention.c_str(), shareOption);
614 return E_INVALID_PARAMETERS;
615 }
616
617 uint64_t accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID();
618 bool isSystemApp = TokenIdKit::IsSystemAppByFullTokenID(accessTokenIDEx);
619 bool hasSharePermission = VerifyPermission(MANAGE_UDMF_APP_SHARE_OPTION, IPCSkeleton::GetCallingTokenID());
620 if (!isSystemApp && !hasSharePermission) {
621 ZLOGE("No system or shareOption permission,intention:%{public}s", intention.c_str());
622 return E_NO_PERMISSION;
623 }
624 auto store = StoreCache::GetInstance().GetStore(intention);
625 if (store == nullptr) {
626 ZLOGE("Get store failed:%{public}s", intention.c_str());
627 return E_DB_ERROR;
628 }
629
630 std::string shareOptionTmp;
631 if (store->GetLocal(std::to_string(accessTokenIDEx), shareOptionTmp) == E_OK) {
632 ZLOGE("SetAppShareOption failed,shareOption already set:%{public}s", shareOptionTmp.c_str());
633 return E_SETTINGS_EXISTED;
634 }
635
636 if (store->PutLocal(std::to_string(accessTokenIDEx), ShareOptionsUtil::GetEnumStr(shareOption)) != E_OK) {
637 ZLOGE("Store get unifiedData failed:%{public}d", shareOption);
638 return E_DB_ERROR;
639 }
640 return E_OK;
641 }
642
GetAppShareOption(const std::string & intention,int32_t & shareOption)643 int32_t UdmfServiceImpl::GetAppShareOption(const std::string &intention, int32_t &shareOption)
644 {
645 if (intention.empty()) {
646 ZLOGE("intention is empty:%{public}s", intention.c_str());
647 return E_INVALID_PARAMETERS;
648 }
649 uint64_t accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID();
650 auto store = StoreCache::GetInstance().GetStore(intention);
651 if (store == nullptr) {
652 ZLOGE("Get store failed:%{public}s", intention.c_str());
653 return E_DB_ERROR;
654 }
655 std::string appShareOption;
656 int32_t ret = store->GetLocal(std::to_string(accessTokenIDEx), appShareOption);
657 if (ret != E_OK) {
658 ZLOGW("GetLocal failed:%{public}s", intention.c_str());
659 return ret;
660 }
661 ZLOGI("GetLocal ok intention:%{public}s,appShareOption:%{public}s", intention.c_str(), appShareOption.c_str());
662 shareOption = ShareOptionsUtil::GetEnumNum(appShareOption);
663 return E_OK;
664 }
665
RemoveAppShareOption(const std::string & intention)666 int32_t UdmfServiceImpl::RemoveAppShareOption(const std::string &intention)
667 {
668 if (intention.empty()) {
669 ZLOGE("intention: %{public}s is invalid.", intention.c_str());
670 return E_INVALID_PARAMETERS;
671 }
672 uint64_t accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID();
673 bool isSystemApp = TokenIdKit::IsSystemAppByFullTokenID(accessTokenIDEx);
674 bool hasSharePermission = VerifyPermission(MANAGE_UDMF_APP_SHARE_OPTION, IPCSkeleton::GetCallingTokenID());
675 if (!isSystemApp && !hasSharePermission) {
676 ZLOGE("No system or shareOption permission:%{public}s", intention.c_str());
677 return E_NO_PERMISSION;
678 }
679 auto store = StoreCache::GetInstance().GetStore(intention);
680 if (store == nullptr) {
681 ZLOGE("Get store failed:%{public}s", intention.c_str());
682 return E_DB_ERROR;
683 }
684
685 UnifiedData unifiedData;
686 if (store->DeleteLocal(std::to_string(accessTokenIDEx)) != E_OK) {
687 ZLOGE("Store DeleteLocal failed:%{public}s", intention.c_str());
688 return E_DB_ERROR;
689 }
690 return E_OK;
691 }
692
OnInitialize()693 int32_t UdmfServiceImpl::OnInitialize()
694 {
695 ZLOGD("start");
696 Status status = LifeCycleManager::GetInstance().OnStart();
697 if (status != E_OK) {
698 ZLOGE("OnStart execute failed, status: %{public}d", status);
699 }
700 status = LifeCycleManager::GetInstance().StartLifeCycleTimer();
701 if (status != E_OK) {
702 ZLOGE("StartLifeCycleTimer start failed, status: %{public}d", status);
703 }
704 return DistributedData::FeatureSystem::STUB_SUCCESS;
705 }
706
QueryDataCommon(const QueryOption & query,std::vector<UnifiedData> & dataSet,std::shared_ptr<Store> & store)707 int32_t UdmfServiceImpl::QueryDataCommon(
708 const QueryOption &query, std::vector<UnifiedData> &dataSet, std::shared_ptr<Store> &store)
709 {
710 auto find = UD_INTENTION_MAP.find(query.intention);
711 std::string intention = find == UD_INTENTION_MAP.end() ? intention : find->second;
712 UnifiedKey key(query.key);
713 if (!UnifiedDataUtils::IsValidOptions(key, intention, UD_INTENTION_MAP.at(UD_INTENTION_DATA_HUB))) {
714 ZLOGE("Unified key: %{public}s and intention: %{public}s is invalid.", query.key.c_str(), intention.c_str());
715 return E_INVALID_PARAMETERS;
716 }
717 std::string dataPrefix;
718 if (key.key.empty()) {
719 dataPrefix = DATA_PREFIX + intention;
720 } else {
721 dataPrefix = UnifiedKey(key.key).GetPropertyKey();
722 intention = key.intention;
723 }
724 ZLOGD("dataPrefix = %{public}s, intention: %{public}s.", dataPrefix.c_str(), intention.c_str());
725 store = StoreCache::GetInstance().GetStore(intention);
726 if (store == nullptr) {
727 ZLOGE("Get store failed:%{public}s", intention.c_str());
728 return E_DB_ERROR;
729 }
730 if (store->GetBatchData(dataPrefix, dataSet) != E_OK) {
731 ZLOGE("Get dataSet failed, dataPrefix: %{public}s.", dataPrefix.c_str());
732 return E_DB_ERROR;
733 }
734 return E_OK;
735 }
736
OnBind(const BindInfo & bindInfo)737 int32_t UdmfServiceImpl::OnBind(const BindInfo &bindInfo)
738 {
739 executors_ = bindInfo.executors;
740 StoreCache::GetInstance().SetThreadPool(bindInfo.executors);
741 LifeCycleManager::GetInstance().SetThreadPool(bindInfo.executors);
742 return 0;
743 }
744
ObtainAsynProcess(AsyncProcessInfo & processInfo)745 int32_t UdmfServiceImpl::ObtainAsynProcess(AsyncProcessInfo &processInfo)
746 {
747 if (processInfo.businessUdKey.empty()) {
748 return E_INVALID_PARAMETERS;
749 }
750 std::lock_guard<std::mutex> lock(mutex_);
751 if (asyncProcessInfoMap_.empty()) {
752 processInfo.syncStatus = AsyncTaskStatus::ASYNC_SUCCESS;
753 processInfo.srcDevName = "Local";
754 return E_OK;
755 }
756 auto it = asyncProcessInfoMap_.find(processInfo.businessUdKey);
757 if (it == asyncProcessInfoMap_.end()) {
758 processInfo.syncStatus = AsyncTaskStatus::ASYNC_SUCCESS;
759 processInfo.srcDevName = "Local";
760 return E_OK;
761 }
762 auto asyncProcessInfo = asyncProcessInfoMap_.at(processInfo.businessUdKey);
763 processInfo.syncStatus = asyncProcessInfo.syncStatus;
764 processInfo.srcDevName = asyncProcessInfo.srcDevName;
765 return E_OK;
766 }
767
ClearAsynProcessByKey(const std::string & businessUdKey)768 int32_t UdmfServiceImpl::ClearAsynProcessByKey(const std::string & businessUdKey)
769 {
770 ZLOGI("ClearAsynProcessByKey begin.");
771 std::lock_guard<std::mutex> lock(mutex_);
772 if (asyncProcessInfoMap_.find(businessUdKey) == asyncProcessInfoMap_.end()) {
773 return E_OK;
774 }
775 asyncProcessInfoMap_.erase(businessUdKey);
776 return E_OK;
777 }
778
ResolveAutoLaunch(const std::string & identifier,DBLaunchParam & param)779 int32_t UdmfServiceImpl::ResolveAutoLaunch(const std::string &identifier, DBLaunchParam ¶m)
780 {
781 ZLOGI("user:%{public}s appId:%{public}s storeId:%{public}s identifier:%{public}s", param.userId.c_str(),
782 param.appId.c_str(), DistributedData::Anonymous::Change(param.storeId).c_str(),
783 DistributedData::Anonymous::Change(identifier).c_str());
784
785 std::vector<StoreMetaData> metaData;
786 auto prefix = StoreMetaData::GetPrefix({ DmAdapter::GetInstance().GetLocalDevice().uuid });
787 if (!DistributedData::MetaDataManager::GetInstance().LoadMeta(prefix, metaData)) {
788 ZLOGE("no meta data appId:%{public}s", param.appId.c_str());
789 return E_NOT_FOUND;
790 }
791
792 for (const auto &storeMeta : metaData) {
793 if (storeMeta.storeType < StoreMetaData::StoreType::STORE_KV_BEGIN ||
794 storeMeta.storeType > StoreMetaData::StoreType::STORE_KV_END ||
795 storeMeta.appId != DistributedData::Bootstrap::GetInstance().GetProcessLabel()) {
796 continue;
797 }
798 auto identifierTag = DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier("", storeMeta.appId,
799 storeMeta.storeId, true);
800 if (identifier != identifierTag) {
801 continue;
802 }
803 auto store = StoreCache::GetInstance().GetStore(storeMeta.storeId);
804 if (store == nullptr) {
805 ZLOGE("GetStore fail, storeId:%{public}s", DistributedData::Anonymous::Change(storeMeta.storeId).c_str());
806 continue;
807 }
808 ZLOGI("storeId:%{public}s,appId:%{public}s,user:%{public}s",
809 DistributedData::Anonymous::Change(storeMeta.storeId).c_str(),
810 storeMeta.appId.c_str(), storeMeta.user.c_str());
811 return E_OK;
812 }
813 return E_OK;
814 }
815
VerifyPermission(const std::string & permission,uint32_t callerTokenId)816 bool UdmfServiceImpl::VerifyPermission(const std::string &permission, uint32_t callerTokenId)
817 {
818 if (permission.empty()) {
819 return true;
820 }
821 int status = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerTokenId, permission);
822 if (status != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
823 ZLOGE("Permission denied. status:%{public}d, token:0x%{public}x, permission:%{public}s",
824 status, callerTokenId, permission.c_str());
825 return false;
826 }
827 return true;
828 }
829
HasDatahubPriviledge(const std::string & bundleName)830 bool UdmfServiceImpl::HasDatahubPriviledge(const std::string &bundleName)
831 {
832 uint64_t accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID();
833 bool isSystemApp = TokenIdKit::IsSystemAppByFullTokenID(accessTokenIDEx);
834 return std::find(std::begin(HAP_LIST), std::end(HAP_LIST), bundleName) != std::end(HAP_LIST) && isSystemApp;
835 }
836
RegisterAsyncProcessInfo(const std::string & businessUdKey)837 void UdmfServiceImpl::RegisterAsyncProcessInfo(const std::string &businessUdKey)
838 {
839 AsyncProcessInfo info;
840 std::lock_guard<std::mutex> lock(mutex_);
841 asyncProcessInfoMap_.insert_or_assign(businessUdKey, std::move(info));
842 }
843
OnUserChange(uint32_t code,const std::string & user,const std::string & account)844 int32_t UdmfServiceImpl::OnUserChange(uint32_t code, const std::string &user, const std::string &account)
845 {
846 ZLOGI("user change, code:%{public}u, user:%{public}s, account:%{public}s", code, user.c_str(), account.c_str());
847 if (code == static_cast<uint32_t>(DistributedData::AccountStatus::DEVICE_ACCOUNT_SWITCHED)) {
848 StoreCache::GetInstance().CloseStores();
849 }
850 return Feature::OnUserChange(code, user, account);
851 }
852
TransferToEntriesIfNeed(const QueryOption & query,UnifiedData & unifiedData)853 void UdmfServiceImpl::TransferToEntriesIfNeed(const QueryOption &query, UnifiedData &unifiedData)
854 {
855 if (unifiedData.IsNeedTransferToEntries() && IsNeedTransferDeviceType(query)) {
856 unifiedData.ConvertRecordsToEntries();
857 }
858 }
859
IsNeedTransferDeviceType(const QueryOption & query)860 bool UdmfServiceImpl::IsNeedTransferDeviceType(const QueryOption &query)
861 {
862 auto deviceInfo = DmAdapter::GetInstance().GetLocalDevice();
863 if (deviceInfo.deviceType != DEVICE_TYPE_PC && deviceInfo.deviceType != DEVICE_TYPE_PAD
864 && deviceInfo.deviceType != DEVICE_TYPE_2IN1) {
865 return false;
866 }
867 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
868 if (samgrProxy == nullptr) {
869 ZLOGE("Failed to get system ability mgr.");
870 return false;
871 }
872 auto bundleMgrProxy = samgrProxy->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
873 if (bundleMgrProxy == nullptr) {
874 ZLOGE("Failed to Get BMS SA.");
875 return false;
876 }
877 auto bundleManager = iface_cast<AppExecFwk::IBundleMgr>(bundleMgrProxy);
878 if (bundleManager == nullptr) {
879 ZLOGE("Failed to get bundle manager");
880 return false;
881 }
882 std::string bundleName;
883 PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName);
884 int32_t userId = DistributedData::AccountDelegate::GetInstance()->GetUserByToken(
885 IPCSkeleton::GetCallingFullTokenID());
886 AppExecFwk::BundleInfo bundleInfo;
887 bundleManager->GetBundleInfoV9(bundleName, static_cast<int32_t>(
888 AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE), bundleInfo, userId);
889 for (const auto &hapModuleInfo : bundleInfo.hapModuleInfos) {
890 if (std::find(hapModuleInfo.deviceTypes.begin(), hapModuleInfo.deviceTypes.end(),
891 DEVICE_PHONE_TAG) == hapModuleInfo.deviceTypes.end()
892 && std::find(hapModuleInfo.deviceTypes.begin(), hapModuleInfo.deviceTypes.end(),
893 DEVICE_DEFAULT_TAG) == hapModuleInfo.deviceTypes.end()
894 && std::find(hapModuleInfo.deviceTypes.begin(), hapModuleInfo.deviceTypes.end(),
895 DEVICE_2IN1_TAG) != hapModuleInfo.deviceTypes.end()) {
896 return true;
897 }
898 }
899 return false;
900 }
901 } // namespace UDMF
902 } // namespace OHOS