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