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 "account/account_delegate.h"
25 #include "bootstrap.h"
26 #include "bundle_info.h"
27 #include "bundlemgr/bundle_mgr_proxy.h"
28 #include "checker/checker_manager.h"
29 #include "checker_manager.h"
30 #include "device_manager_adapter.h"
31 #include "device_matrix.h"
32 #include "iservice_registry.h"
33 #include "lifecycle/lifecycle_manager.h"
34 #include "log_print.h"
35 #include "metadata/capability_meta_data.h"
36 #include "metadata/store_meta_data.h"
37 #include "metadata/meta_data_manager.h"
38 #include "preprocess_utils.h"
39 #include "dfx/reporter.h"
40 #include "system_ability_definition.h"
41 #include "uri_permission_manager.h"
42 #include "udmf_radar_reporter.h"
43 #include "udmf_utils.h"
44 #include "unified_data_helper.h"
45 #include "utils/anonymous.h"
46 #include "permission_validator.h"
47
48 namespace OHOS {
49 namespace UDMF {
50 using namespace Security::AccessToken;
51 using namespace OHOS::DistributedHardware;
52 using namespace OHOS::DistributedData;
53 using FeatureSystem = DistributedData::FeatureSystem;
54 using UdmfBehaviourMsg = OHOS::DistributedDataDfx::UdmfBehaviourMsg;
55 using Reporter = OHOS::DistributedDataDfx::Reporter;
56 using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter;
57 using StoreMetaData = OHOS::DistributedData::StoreMetaData;
58 using namespace RadarReporter;
59 using namespace DistributedKv;
60 constexpr const char *DRAG_AUTHORIZED_PROCESSES[] = {"msdp_sa", "collaboration_service"};
61 constexpr const char *DATA_PREFIX = "udmf://";
62 constexpr const char *FILE_SCHEME = "file";
63 constexpr const char *PRIVILEGE_READ_AND_KEEP = "readAndKeep";
64 constexpr const char *MANAGE_UDMF_APP_SHARE_OPTION = "ohos.permission.MANAGE_UDMF_APP_SHARE_OPTION";
65 constexpr const char *DEVICE_2IN1_TAG = "2in1";
66 constexpr const char *DEVICE_PHONE_TAG = "phone";
67 constexpr const char *DEVICE_DEFAULT_TAG = "default";
68 constexpr const char *HAP_LIST[] = {"com.ohos.pasteboarddialog"};
69 constexpr uint32_t FOUNDATION_UID = 5523;
70 __attribute__((used)) UdmfServiceImpl::Factory UdmfServiceImpl::factory_;
Factory()71 UdmfServiceImpl::Factory::Factory()
72 {
73 ZLOGI("Register udmf creator!");
74 FeatureSystem::GetInstance().RegisterCreator("udmf", [this]() {
75 if (product_ == nullptr) {
76 product_ = std::make_shared<UdmfServiceImpl>();
77 }
78 return product_;
79 }, FeatureSystem::BIND_NOW);
80 }
81
~Factory()82 UdmfServiceImpl::Factory::~Factory()
83 {
84 product_ = nullptr;
85 }
86
UdmfServiceImpl()87 UdmfServiceImpl::UdmfServiceImpl()
88 {
89 CheckerManager::GetInstance().LoadCheckers();
90 }
91
SetData(CustomOption & option,UnifiedData & unifiedData,std::string & key)92 int32_t UdmfServiceImpl::SetData(CustomOption &option, UnifiedData &unifiedData, std::string &key)
93 {
94 ZLOGD("start");
95 int32_t res = E_OK;
96 UdmfBehaviourMsg msg;
97 std::string types;
98 auto find = UD_INTENTION_MAP.find(option.intention);
99 msg.channel = find == UD_INTENTION_MAP.end() ? "invalid" : find->second;
100 msg.operation = "insert";
101 std::string bundleName;
102 if (!PreProcessUtils::GetHapBundleNameByToken(option.tokenId, bundleName)) {
103 msg.appId = "unknown";
104 res = E_ERROR;
105 } else {
106 RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__),
107 BizScene::SET_DATA, SetDataStage::SET_DATA_SERVICE_BEGIN, StageRes::IDLE, bundleName);
108 msg.appId = bundleName;
109 res = SaveData(option, unifiedData, key);
110 }
111 auto errFind = ERROR_MAP.find(res);
112 msg.result = errFind == ERROR_MAP.end() ? "E_ERROR" : errFind->second;
113
114 for (const auto &record : unifiedData.GetRecords()) {
115 for (const auto &type : record->GetUtdIds()) {
116 types.append("-").append(type);
117 }
118 }
119 msg.dataType = types;
120 msg.dataSize = unifiedData.GetSize();
121 Reporter::GetInstance()->GetBehaviourReporter()->UDMFReport(msg);
122 return res;
123 }
124
SaveData(CustomOption & option,UnifiedData & unifiedData,std::string & key)125 int32_t UdmfServiceImpl::SaveData(CustomOption &option, UnifiedData &unifiedData, std::string &key)
126 {
127 if (!unifiedData.IsValid()) {
128 ZLOGE("UnifiedData is invalid.");
129 return E_INVALID_PARAMETERS;
130 }
131 if (!UnifiedDataUtils::IsValidIntention(option.intention)) {
132 ZLOGE("Invalid parameters intention: %{public}d.", option.intention);
133 return E_INVALID_PARAMETERS;
134 }
135 // imput runtime info before put it into store and save one privilege
136 if (PreProcessUtils::FillRuntimeInfo(unifiedData, option) != E_OK) {
137 ZLOGE("Imputation failed");
138 return E_ERROR;
139 }
140 std::string intention = unifiedData.GetRuntime()->key.intention;
141 if (intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) {
142 int32_t ret = PreProcessUtils::SetRemoteUri(option.tokenId, unifiedData);
143 if (ret != E_OK) {
144 ZLOGW("SetRemoteUri failed, ret: %{public}d, bundleName:%{public}s.", ret,
145 unifiedData.GetRuntime()->createPackage.c_str());
146 }
147 }
148 PreProcessUtils::SetRecordUid(unifiedData);
149 auto store = StoreCache::GetInstance().GetStore(intention);
150 if (store == nullptr) {
151 ZLOGE("Get store failed:%{public}s", intention.c_str());
152 return E_DB_ERROR;
153 }
154 int32_t status = store->Put(unifiedData);
155 if (status != E_OK) {
156 ZLOGE("Put unified data failed:%{public}s, status:%{public}d", intention.c_str(), status);
157 HandleDbError(intention, status);
158 return E_DB_ERROR;
159 }
160 key = unifiedData.GetRuntime()->key.GetUnifiedKey();
161 ZLOGD("Put unified data successful, key: %{public}s.", key.c_str());
162 return E_OK;
163 }
164
GetData(const QueryOption & query,UnifiedData & unifiedData)165 int32_t UdmfServiceImpl::GetData(const QueryOption &query, UnifiedData &unifiedData)
166 {
167 ZLOGD("start");
168 int32_t res = E_OK;
169 UdmfBehaviourMsg msg;
170 std::string types;
171 auto find = UD_INTENTION_MAP.find(query.intention);
172 msg.channel = find == UD_INTENTION_MAP.end() ? "invalid" : find->second;
173 msg.operation = "insert";
174 std::string bundleName;
175 if (!PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName)) {
176 msg.appId = "unknown";
177 res = E_ERROR;
178 } else {
179 msg.appId = bundleName;
180 res = RetrieveData(query, unifiedData);
181 }
182 TransferToEntriesIfNeed(query, unifiedData);
183 auto errFind = ERROR_MAP.find(res);
184 msg.result = errFind == ERROR_MAP.end() ? "E_ERROR" : errFind->second;
185 for (const auto &record : unifiedData.GetRecords()) {
186 for (const auto &type : record->GetUtdIds()) {
187 types.append("-").append(type);
188 }
189 }
190 msg.dataType = types;
191 msg.dataSize = unifiedData.GetSize();
192 Reporter::GetInstance()->GetBehaviourReporter()->UDMFReport(msg);
193 return res;
194 }
195
CheckDragParams(UnifiedKey & key,const QueryOption & query)196 bool UdmfServiceImpl::CheckDragParams(UnifiedKey &key, const QueryOption &query)
197 {
198 if (!key.IsValid()) {
199 ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str());
200 return false;
201 }
202 if (key.intention != UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) {
203 ZLOGE("Invalid intention:%{public}s", key.intention.c_str());
204 return false;
205 }
206 return true;
207 }
208
RetrieveData(const QueryOption & query,UnifiedData & unifiedData)209 int32_t UdmfServiceImpl::RetrieveData(const QueryOption &query, UnifiedData &unifiedData)
210 {
211 UnifiedKey key(query.key);
212 if (!CheckDragParams(key, query)) {
213 return E_INVALID_PARAMETERS;
214 }
215 auto store = StoreCache::GetInstance().GetStore(key.intention);
216 if (store == nullptr) {
217 ZLOGE("Get store failed:%{public}s", key.intention.c_str());
218 return E_DB_ERROR;
219 }
220 int32_t res = store->Get(query.key, unifiedData);
221 if (res != E_OK) {
222 ZLOGE("Get data failed,res:%{public}d,key:%{public}s", res, query.key.c_str());
223 HandleDbError(key.intention, res);
224 return res;
225 }
226
227 if (!unifiedData.IsComplete()) {
228 ZLOGE("Get data incomplete,key:%{public}s", query.key.c_str());
229 return E_NOT_FOUND;
230 }
231 std::shared_ptr<Runtime> runtime = unifiedData.GetRuntime();
232 if (runtime == nullptr) {
233 return E_DB_ERROR;
234 }
235
236 res = VerifyDataAccessPermission(runtime, query, unifiedData);
237 if (res != E_OK) {
238 return res;
239 }
240
241 if (key.intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) {
242 int32_t ret = ProcessUri(query, unifiedData);
243 if (ret != E_OK) {
244 RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
245 BizScene::GET_DATA, GetDataStage::GRANT_URI_PERMISSION, StageRes::FAILED, ret);
246 ZLOGE("ProcessUri failed:%{public}d", ret);
247 return E_NO_PERMISSION;
248 }
249 }
250 if (!IsReadAndKeep(runtime->privileges, query)) {
251 if (LifeCycleManager::GetInstance().OnGot(key) != E_OK) {
252 ZLOGE("Remove data failed:%{public}s", key.intention.c_str());
253 return E_DB_ERROR;
254 }
255 }
256
257 {
258 std::lock_guard<std::recursive_mutex> lock(cacheMutex_);
259 privilegeCache_.erase(query.key);
260 }
261 PreProcessUtils::SetRemoteData(unifiedData);
262 return E_OK;
263 }
264
VerifyDataAccessPermission(std::shared_ptr<Runtime> runtime,const QueryOption & query,const UnifiedData & unifiedData)265 int32_t UdmfServiceImpl::VerifyDataAccessPermission(std::shared_ptr<Runtime> runtime, const QueryOption &query,
266 const UnifiedData &unifiedData)
267 {
268 CheckerManager::CheckInfo info;
269 info.tokenId = query.tokenId;
270
271 if (!CheckerManager::GetInstance().IsValid(runtime->privileges, info) && !IsPermissionInCache(query)) {
272 RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
273 BizScene::GET_DATA, GetDataStage::VERIFY_PRIVILEGE, StageRes::FAILED, E_NO_PERMISSION);
274 ZLOGE("Get data failed,key:%{public}s", query.key.c_str());
275 return E_NO_PERMISSION;
276 }
277
278 return E_OK;
279 }
280
IsPermissionInCache(const QueryOption & query)281 bool UdmfServiceImpl::IsPermissionInCache(const QueryOption &query)
282 {
283 std::lock_guard<std::recursive_mutex> lock(cacheMutex_);
284 auto iter = privilegeCache_.find(query.key);
285 if (iter != privilegeCache_.end() && iter->second.tokenId == query.tokenId) {
286 return true;
287 }
288 return false;
289 }
290
IsReadAndKeep(const std::vector<Privilege> & privileges,const QueryOption & query)291 bool UdmfServiceImpl::IsReadAndKeep(const std::vector<Privilege> &privileges, const QueryOption &query)
292 {
293 for (const auto &privilege : privileges) {
294 if (privilege.tokenId == query.tokenId && privilege.readPermission == PRIVILEGE_READ_AND_KEEP) {
295 return true;
296 }
297 }
298
299 std::lock_guard<std::recursive_mutex> lock(cacheMutex_);
300 auto iter = privilegeCache_.find(query.key);
301 if (iter != privilegeCache_.end() && iter->second.tokenId == query.tokenId &&
302 iter->second.readPermission == PRIVILEGE_READ_AND_KEEP) {
303 return true;
304 }
305 return false;
306 }
307
ProcessUri(const QueryOption & query,UnifiedData & unifiedData)308 int32_t UdmfServiceImpl::ProcessUri(const QueryOption &query, UnifiedData &unifiedData)
309 {
310 std::string localDeviceId = PreProcessUtils::GetLocalDeviceId();
311 std::vector<Uri> allUri;
312 int32_t verifyRes = ProcessCrossDeviceData(query.tokenId, unifiedData, allUri);
313 if (verifyRes != E_OK) {
314 ZLOGE("verify unifieddata fail, key=%{public}s, stauts=%{public}d", query.key.c_str(), verifyRes);
315 return verifyRes;
316 }
317 std::string bundleName;
318 if (!PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName)) {
319 ZLOGE("Get bundleName fail,key=%{public}s,tokenId=%d", query.key.c_str(), query.tokenId);
320 return E_ERROR;
321 }
322 std::string sourceDeviceId = unifiedData.GetRuntime()->deviceId;
323 if (localDeviceId == sourceDeviceId && query.tokenId == unifiedData.GetRuntime()->tokenId) {
324 ZLOGW("No uri permissions needed,queryKey=%{public}s", query.key.c_str());
325 return E_OK;
326 }
327 if (UriPermissionManager::GetInstance().GrantUriPermission(allUri, query.tokenId, query.key) != E_OK) {
328 ZLOGE("GrantUriPermission fail, bundleName=%{public}s, key=%{public}s.",
329 bundleName.c_str(), query.key.c_str());
330 return E_NO_PERMISSION;
331 }
332 return E_OK;
333 }
334
ProcessCrossDeviceData(uint32_t tokenId,UnifiedData & unifiedData,std::vector<Uri> & uris)335 int32_t UdmfServiceImpl::ProcessCrossDeviceData(uint32_t tokenId, UnifiedData &unifiedData, std::vector<Uri> &uris)
336 {
337 if (unifiedData.GetRuntime() == nullptr) {
338 ZLOGE("Get runtime empty!");
339 return E_DB_ERROR;
340 }
341 bool isLocal = PreProcessUtils::GetLocalDeviceId() == unifiedData.GetRuntime()->deviceId;
342 auto records = unifiedData.GetRecords();
343 bool hasError = false;
344 PreProcessUtils::ProcessFileType(records, [&] (std::shared_ptr<Object> obj) {
345 if (hasError) {
346 return false;
347 }
348 std::string oriUri;
349 obj->GetValue(ORI_URI, oriUri);
350 if (oriUri.empty()) {
351 ZLOGW("Get uri is empty.");
352 return false;
353 }
354 Uri uri(oriUri);
355 std::string scheme = uri.GetScheme();
356 std::transform(scheme.begin(), scheme.end(), scheme.begin(), ::tolower);
357 if (!isLocal) {
358 std::string remoteUri;
359 obj->GetValue(REMOTE_URI, remoteUri);
360 if (remoteUri.empty() && scheme == FILE_SCHEME) {
361 ZLOGE("Remote URI required for cross-device");
362 hasError = true;
363 return false;
364 }
365 if (!remoteUri.empty()) {
366 obj->value_.insert_or_assign(ORI_URI, remoteUri); // cross dev, need dis path.
367 uri = Uri(remoteUri);
368 scheme = uri.GetScheme();
369 std::transform(scheme.begin(), scheme.end(), scheme.begin(), ::tolower);
370 }
371 }
372 if (uri.GetAuthority().empty() || scheme != FILE_SCHEME) {
373 ZLOGW("Empty authority or scheme not file");
374 return false;
375 }
376 uris.push_back(uri);
377 return true;
378 });
379 PreProcessUtils::ProcessHtmlFileUris(tokenId, unifiedData, isLocal, uris);
380 return hasError ? E_ERROR : E_OK;
381 }
382
GetBatchData(const QueryOption & query,std::vector<UnifiedData> & unifiedDataSet)383 int32_t UdmfServiceImpl::GetBatchData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet)
384 {
385 ZLOGD("start");
386 std::vector<UnifiedData> dataSet;
387 std::shared_ptr<Store> store;
388 auto status = QueryDataCommon(query, dataSet, store);
389 if (status != E_OK) {
390 ZLOGE("QueryDataCommon failed.");
391 return status;
392 }
393 if (dataSet.empty()) {
394 ZLOGW("DataSet empty,key:%{public}s,intention:%{public}d", query.key.c_str(), query.intention);
395 return E_OK;
396 }
397 for (auto &data : dataSet) {
398 if (query.intention == Intention::UD_INTENTION_DATA_HUB &&
399 data.GetRuntime()->visibility == VISIBILITY_OWN_PROCESS &&
400 query.tokenId != data.GetRuntime()->tokenId) {
401 continue;
402 } else {
403 unifiedDataSet.push_back(std::move(data));
404 }
405 }
406 if (!IsFileMangerSa() && ProcessData(query, unifiedDataSet) != E_OK) {
407 ZLOGE("Query no permission.");
408 return E_NO_PERMISSION;
409 }
410 return E_OK;
411 }
412
UpdateData(const QueryOption & query,UnifiedData & unifiedData)413 int32_t UdmfServiceImpl::UpdateData(const QueryOption &query, UnifiedData &unifiedData)
414 {
415 UnifiedKey key(query.key);
416 if (!IsValidInput(query, unifiedData, key)) {
417 return E_INVALID_PARAMETERS;
418 }
419 std::string bundleName;
420 std::string specificBundleName;
421 if (!PreProcessUtils::GetSpecificBundleNameByTokenId(query.tokenId, specificBundleName, bundleName)) {
422 ZLOGE("GetSpecificBundleNameByTokenId failed, tokenid:%{public}u", query.tokenId);
423 return E_ERROR;
424 }
425 if (key.bundleName != specificBundleName && !HasDatahubPriviledge(bundleName)) {
426 ZLOGE("update data failed by %{public}s, key: %{public}s.", bundleName.c_str(), query.key.c_str());
427 return E_INVALID_PARAMETERS;
428 }
429 auto store = StoreCache::GetInstance().GetStore(key.intention);
430 if (store == nullptr) {
431 ZLOGE("Get store failed:%{public}s", key.intention.c_str());
432 return E_DB_ERROR;
433 }
434 UnifiedData data;
435 int32_t res = store->Get(query.key, data);
436 if (res != E_OK) {
437 ZLOGE("Get data failed:%{public}s", key.intention.c_str());
438 HandleDbError(key.intention, res);
439 return res;
440 }
441 auto verifyRes = VerifyUpdatePermission(query, data, bundleName);
442 if (verifyRes != E_OK) {
443 ZLOGE("VerifyUpdatePermission failed:%{public}d, key: %{public}s.", verifyRes, query.key.c_str());
444 return verifyRes;
445 }
446 std::shared_ptr<Runtime> runtime = data.GetRuntime();
447 runtime->lastModifiedTime = PreProcessUtils::GetTimestamp();
448 unifiedData.SetRuntime(*runtime);
449 PreProcessUtils::SetRecordUid(unifiedData);
450 if ((res = store->Update(unifiedData)) != E_OK) {
451 ZLOGE("Unified data update failed:%{public}s", key.intention.c_str());
452 HandleDbError(key.intention, res);
453 return E_DB_ERROR;
454 }
455 return E_OK;
456 }
457
VerifyUpdatePermission(const QueryOption & query,UnifiedData & data,std::string & bundleName)458 int32_t UdmfServiceImpl::VerifyUpdatePermission(const QueryOption &query, UnifiedData &data, std::string &bundleName)
459 {
460 if (data.IsEmpty()) {
461 return E_INVALID_PARAMETERS;
462 }
463 std::shared_ptr<Runtime> runtime = data.GetRuntime();
464 if (runtime == nullptr) {
465 ZLOGE("Invalid parameter, runtime is nullptr.");
466 return E_DB_ERROR;
467 }
468 if (runtime->tokenId != query.tokenId && !HasDatahubPriviledge(bundleName) &&
469 CheckAppId(runtime, bundleName) != E_OK) {
470 ZLOGE("Update failed: tokenId or appId mismatch, bundleName: %{public}s", bundleName.c_str());
471 return E_INVALID_PARAMETERS;
472 }
473 return E_OK;
474 }
475
CheckAppId(std::shared_ptr<Runtime> runtime,const std::string & bundleName)476 int32_t UdmfServiceImpl::CheckAppId(std::shared_ptr<Runtime> runtime, const std::string &bundleName)
477 {
478 if (runtime->appId.empty()) {
479 ZLOGE("Update failed: Invalid parameter, runtime->appId is empty");
480 return E_INVALID_PARAMETERS;
481 }
482 std::string appId = DistributedData::CheckerManager::GetInstance().GetAppId(
483 { IPCSkeleton::GetCallingUid(), runtime->tokenId, bundleName });
484 if (appId.empty() || appId != runtime->appId) {
485 ZLOGE("Update failed: runtime->appId %{public}s and bundleName appId %{public}s mismatch",
486 runtime->appId.c_str(), appId.c_str());
487 return E_INVALID_PARAMETERS;
488 }
489 return E_OK;
490 }
491
DeleteData(const QueryOption & query,std::vector<UnifiedData> & unifiedDataSet)492 int32_t UdmfServiceImpl::DeleteData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet)
493 {
494 ZLOGD("start");
495 UnifiedKey key(query.key);
496 if (!key.IsValid() && !key.key.empty()) {
497 ZLOGE("invalid key, query.key: %{public}s", query.key.c_str());
498 return E_INVALID_PARAMETERS;
499 }
500 std::string intention = FindIntentionMap(query.intention);
501 if (!IsValidOptionsNonDrag(key, intention)) {
502 ZLOGE("invalid option, query.key: %{public}s, intention: %{public}d", query.key.c_str(), query.intention);
503 return E_INVALID_PARAMETERS;
504 }
505 std::vector<UnifiedData> dataSet;
506 std::shared_ptr<Store> store;
507 int32_t status = QueryDataCommon(query, dataSet, store);
508 if (status != E_OK) {
509 ZLOGE("QueryDataCommon failed.");
510 return status;
511 }
512 if (dataSet.empty()) {
513 ZLOGW("DataSet has no data, key: %{public}s, intention: %{public}d.", query.key.c_str(), query.intention);
514 return E_OK;
515 }
516 std::shared_ptr<Runtime> runtime;
517 std::string appId;
518 std::vector<std::string> deleteKeys;
519 for (const auto &data : dataSet) {
520 auto runtime = data.GetRuntime();
521 if (!CheckDeleteDataPermission(appId, runtime, query)) {
522 continue;
523 }
524 unifiedDataSet.push_back(data);
525 deleteKeys.emplace_back(UnifiedKey(runtime->key.key).GetKeyCommonPrefix());
526 }
527 if (deleteKeys.empty()) {
528 ZLOGE("No data to delete for this application");
529 return E_OK;
530 }
531 ZLOGI("Delete data start. size: %{public}zu.", deleteKeys.size());
532 status = store->DeleteBatch(deleteKeys);
533 if (status != E_OK) {
534 ZLOGE("Remove data failed.");
535 HandleDbError(key.intention, status);
536 return E_DB_ERROR;
537 }
538 return E_OK;
539 }
540
CheckDeleteDataPermission(std::string & appId,const std::shared_ptr<Runtime> & runtime,const QueryOption & query)541 bool UdmfServiceImpl::CheckDeleteDataPermission(std::string &appId, const std::shared_ptr<Runtime> &runtime,
542 const QueryOption &query)
543 {
544 if (runtime == nullptr) {
545 ZLOGE("Invalid runtime.");
546 return false;
547 }
548 if (runtime->tokenId == query.tokenId) {
549 return true;
550 }
551 std::string bundleName;
552 std::string specificBundleName;
553 if (!PreProcessUtils::GetSpecificBundleNameByTokenId(query.tokenId, specificBundleName, bundleName)) {
554 ZLOGE("GetSpecificBundleNameByTokenId failed, tokenid:%{public}u", query.tokenId);
555 return false;
556 }
557 if (CheckAppId(runtime, bundleName) != E_OK) {
558 ZLOGE("Delete failed: tokenId or appId mismatch, bundleName: %{public}s", bundleName.c_str());
559 return false;
560 }
561 return true;
562 }
563
GetSummary(const QueryOption & query,Summary & summary)564 int32_t UdmfServiceImpl::GetSummary(const QueryOption &query, Summary &summary)
565 {
566 ZLOGD("start");
567 UnifiedKey key(query.key);
568 if (!key.IsValid()) {
569 ZLOGE("Invalid unified key:%{public}s", 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:%{public}s", key.intention.c_str());
576 return E_DB_ERROR;
577 }
578 int32_t status = store->GetSummary(key, summary);
579 if (status != E_OK) {
580 ZLOGE("Store get summary failed:%{public}s", key.intention.c_str());
581 HandleDbError(key.intention, status);
582 return E_DB_ERROR;
583 }
584 return E_OK;
585 }
586
AddPrivilege(const QueryOption & query,Privilege & privilege)587 int32_t UdmfServiceImpl::AddPrivilege(const QueryOption &query, Privilege &privilege)
588 {
589 ZLOGD("start");
590 UnifiedKey key(query.key);
591 if (!key.IsValid()) {
592 ZLOGE("Invalid unified key:%{public}s", query.key.c_str());
593 return E_INVALID_PARAMETERS;
594 }
595
596 std::string processName;
597 if (!PreProcessUtils::GetNativeProcessNameByToken(query.tokenId, processName)) {
598 ZLOGE("GetNativeProcessNameByToken is faild");
599 return E_ERROR;
600 }
601
602 if (CheckAddPrivilegePermission(key, processName, query) != E_OK) {
603 ZLOGE("Intention:%{public}s no permission", key.intention.c_str());
604 return E_NO_PERMISSION;
605 }
606 if (!UTILS::IsNativeCallingToken()) {
607 ZLOGE("Calling Token is not native");
608 return E_NO_PERMISSION;
609 }
610
611 auto store = StoreCache::GetInstance().GetStore(key.intention);
612 if (store == nullptr) {
613 ZLOGE("Get store failed:%{public}s", key.intention.c_str());
614 return E_DB_ERROR;
615 }
616
617 Runtime runtime;
618 int32_t res = store->GetRuntime(query.key, runtime);
619 if (res == E_NOT_FOUND) {
620 std::lock_guard<std::recursive_mutex> lock(cacheMutex_);
621 privilegeCache_[query.key] = privilege;
622 ZLOGW("Add privilege in cache, key: %{public}s.", query.key.c_str());
623 return E_OK;
624 }
625 if (res != E_OK) {
626 ZLOGE("Get runtime failed, res:%{public}d, key:%{public}s.", res, query.key.c_str());
627 HandleDbError(key.intention, res);
628 return res;
629 }
630 runtime.privileges.emplace_back(privilege);
631 res = store->PutRuntime(query.key, runtime);
632 if (res != E_OK) {
633 ZLOGE("Update runtime failed, res:%{public}d, key:%{public}s", res, query.key.c_str());
634 HandleDbError(key.intention, res);
635 }
636 return res;
637 }
638
Sync(const QueryOption & query,const std::vector<std::string> & devices)639 int32_t UdmfServiceImpl::Sync(const QueryOption &query, const std::vector<std::string> &devices)
640 {
641 if (!UTILS::IsTokenNative() ||
642 !DistributedKv::PermissionValidator::GetInstance().CheckSyncPermission(query.tokenId)) {
643 ZLOGE("Tokenid permission verification failed!");
644 return E_NO_PERMISSION;
645 }
646 RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__),
647 BizScene::SYNC_DATA, SyncDataStage::SYNC_BEGIN, StageRes::IDLE, BizState::DFX_BEGIN);
648 UnifiedKey key(query.key);
649 if (!key.IsValid()) {
650 RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
651 BizScene::SYNC_DATA, SyncDataStage::SYNC_BEGIN, StageRes::FAILED, E_INVALID_PARAMETERS, BizState::DFX_END);
652 ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str());
653 return E_INVALID_PARAMETERS;
654 }
655 RegisterAsyncProcessInfo(query.key);
656 return StoreSync(key, query, devices);
657 }
658
StoreSync(const UnifiedKey & key,const QueryOption & query,const std::vector<std::string> & devices)659 int32_t UdmfServiceImpl::StoreSync(const UnifiedKey &key, const QueryOption &query,
660 const std::vector<std::string> &devices)
661 {
662 auto store = StoreCache::GetInstance().GetStore(key.intention);
663 if (store == nullptr) {
664 RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
665 BizScene::SYNC_DATA, SyncDataStage::SYNC_BEGIN, StageRes::FAILED, E_DB_ERROR, BizState::DFX_END);
666 ZLOGE("Get store failed:%{public}s", key.intention.c_str());
667 return E_DB_ERROR;
668 }
669 auto callback = [this, query](AsyncProcessInfo &syncInfo) {
670 if (query.key.empty()) {
671 return;
672 }
673 syncInfo.businessUdKey = query.key;
674 std::lock_guard<std::mutex> lock(mutex_);
675 asyncProcessInfoMap_.insert_or_assign(syncInfo.businessUdKey, syncInfo);
676 };
677 RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__),
678 BizScene::SYNC_DATA, SyncDataStage::SYNC_BEGIN, StageRes::SUCCESS);
679 int userId = 0;
680 if (!AccountDelegate::GetInstance()->QueryForegroundUserId(userId)) {
681 ZLOGE("QueryForegroundUserId failed");
682 return E_ERROR;
683 }
684 auto meta = BuildMeta(key.intention, userId);
685 auto uuids = DmAdapter::GetInstance().ToUUID(devices);
686 if (IsNeedMetaSync(meta, uuids)) {
687 bool res = MetaDataManager::GetInstance().Sync(uuids, [this, devices, callback, store] (auto &results) {
688 auto successRes = ProcessResult(results);
689 if (store->Sync(successRes, callback) != E_OK) {
690 ZLOGE("Store sync failed");
691 RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
692 BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::FAILED, E_DB_ERROR, BizState::DFX_END);
693 }
694 });
695 if (!res) {
696 ZLOGE("Meta sync failed");
697 RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
698 BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::FAILED, E_DB_ERROR, BizState::DFX_END);
699 return E_DB_ERROR;
700 }
701 return E_OK;
702 }
703 if (store->Sync(devices, callback) != E_OK) {
704 ZLOGE("Store sync failed");
705 RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
706 BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::FAILED, E_DB_ERROR, BizState::DFX_END);
707 return UDMF::E_DB_ERROR;
708 }
709 return E_OK;
710 }
711
IsNeedMetaSync(const StoreMetaData & meta,const std::vector<std::string> & uuids)712 bool UdmfServiceImpl::IsNeedMetaSync(const StoreMetaData &meta, const std::vector<std::string> &uuids)
713 {
714 using namespace OHOS::DistributedData;
715 bool isAfterMeta = false;
716 for (const auto &uuid : uuids) {
717 auto metaData = meta;
718 metaData.deviceId = uuid;
719 CapMetaData capMeta;
720 auto capKey = CapMetaRow::GetKeyFor(uuid);
721 if (!MetaDataManager::GetInstance().LoadMeta(std::string(capKey.begin(), capKey.end()), capMeta) ||
722 !MetaDataManager::GetInstance().LoadMeta(metaData.GetKeyWithoutPath(), metaData)) {
723 isAfterMeta = true;
724 break;
725 }
726 auto [exist, mask] = DeviceMatrix::GetInstance().GetRemoteMask(uuid);
727 if ((mask & DeviceMatrix::META_STORE_MASK) == DeviceMatrix::META_STORE_MASK) {
728 isAfterMeta = true;
729 break;
730 }
731 auto [existLocal, localMask] = DeviceMatrix::GetInstance().GetMask(uuid);
732 if ((localMask & DeviceMatrix::META_STORE_MASK) == DeviceMatrix::META_STORE_MASK) {
733 isAfterMeta = true;
734 break;
735 }
736 }
737 return isAfterMeta;
738 }
739
IsRemoteData(const QueryOption & query,bool & result)740 int32_t UdmfServiceImpl::IsRemoteData(const QueryOption &query, bool &result)
741 {
742 UnifiedKey key(query.key);
743 if (!key.IsValid()) {
744 ZLOGE("Invalid unified key:%{public}s", query.key.c_str());
745 return E_INVALID_PARAMETERS;
746 }
747
748 auto store = StoreCache::GetInstance().GetStore(key.intention);
749 if (store == nullptr) {
750 ZLOGE("Get store failed:%{public}s", key.intention.c_str());
751 return E_DB_ERROR;
752 }
753
754 Runtime runtime;
755 int32_t res = store->GetRuntime(query.key, runtime);
756 if (res != E_OK) {
757 ZLOGE("Get runtime failed, res:%{public}d, key:%{public}s.", res, query.key.c_str());
758 HandleDbError(key.intention, res);
759 return E_DB_ERROR;
760 }
761
762 std::string localDeviceId = PreProcessUtils::GetLocalDeviceId();
763 if (localDeviceId != runtime.deviceId) {
764 result = true;
765 }
766 return E_OK;
767 }
768
SetAppShareOption(const std::string & intention,int32_t shareOption)769 int32_t UdmfServiceImpl::SetAppShareOption(const std::string &intention, int32_t shareOption)
770 {
771 if (intention.empty() || shareOption >= SHARE_OPTIONS_BUTT || shareOption < IN_APP) {
772 ZLOGE("para is invalid,intention:%{public}s,shareOption:%{public}d",
773 intention.c_str(), shareOption);
774 return E_INVALID_PARAMETERS;
775 }
776
777 uint64_t accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID();
778 bool isSystemApp = TokenIdKit::IsSystemAppByFullTokenID(accessTokenIDEx);
779 bool hasSharePermission = VerifyPermission(MANAGE_UDMF_APP_SHARE_OPTION, IPCSkeleton::GetCallingTokenID());
780 if (!isSystemApp && !hasSharePermission) {
781 ZLOGE("No system or shareOption permission,intention:%{public}s", intention.c_str());
782 return E_NO_PERMISSION;
783 }
784 auto store = StoreCache::GetInstance().GetStore(intention);
785 if (store == nullptr) {
786 ZLOGE("Get store failed:%{public}s", intention.c_str());
787 return E_DB_ERROR;
788 }
789
790 std::string shareOptionTmp;
791 if (store->GetLocal(std::to_string(accessTokenIDEx), shareOptionTmp) == E_OK) {
792 ZLOGE("SetAppShareOption failed,shareOption already set:%{public}s", shareOptionTmp.c_str());
793 return E_SETTINGS_EXISTED;
794 }
795 int32_t status = store->PutLocal(std::to_string(accessTokenIDEx), ShareOptionsUtil::GetEnumStr(shareOption));
796 if (status != E_OK) {
797 ZLOGE("Store get unifiedData failed:%{public}d", status);
798 HandleDbError(intention, status);
799 return E_DB_ERROR;
800 }
801 return E_OK;
802 }
803
GetAppShareOption(const std::string & intention,int32_t & shareOption)804 int32_t UdmfServiceImpl::GetAppShareOption(const std::string &intention, int32_t &shareOption)
805 {
806 if (intention.empty()) {
807 ZLOGE("intention is empty:%{public}s", intention.c_str());
808 return E_INVALID_PARAMETERS;
809 }
810 uint64_t accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID();
811 auto store = StoreCache::GetInstance().GetStore(intention);
812 if (store == nullptr) {
813 ZLOGE("Get store failed:%{public}s", intention.c_str());
814 return E_DB_ERROR;
815 }
816 std::string appShareOption;
817 int32_t ret = store->GetLocal(std::to_string(accessTokenIDEx), appShareOption);
818 if (ret != E_OK) {
819 ZLOGW("GetLocal failed:%{public}s", intention.c_str());
820 HandleDbError(intention, ret);
821 return ret;
822 }
823 ZLOGI("GetLocal ok intention:%{public}s,appShareOption:%{public}s", intention.c_str(), appShareOption.c_str());
824 shareOption = ShareOptionsUtil::GetEnumNum(appShareOption);
825 return E_OK;
826 }
827
RemoveAppShareOption(const std::string & intention)828 int32_t UdmfServiceImpl::RemoveAppShareOption(const std::string &intention)
829 {
830 if (intention.empty()) {
831 ZLOGE("intention: %{public}s is invalid.", intention.c_str());
832 return E_INVALID_PARAMETERS;
833 }
834 uint64_t accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID();
835 bool isSystemApp = TokenIdKit::IsSystemAppByFullTokenID(accessTokenIDEx);
836 bool hasSharePermission = VerifyPermission(MANAGE_UDMF_APP_SHARE_OPTION, IPCSkeleton::GetCallingTokenID());
837 if (!isSystemApp && !hasSharePermission) {
838 ZLOGE("No system or shareOption permission:%{public}s", intention.c_str());
839 return E_NO_PERMISSION;
840 }
841 auto store = StoreCache::GetInstance().GetStore(intention);
842 if (store == nullptr) {
843 ZLOGE("Get store failed:%{public}s", intention.c_str());
844 return E_DB_ERROR;
845 }
846
847 UnifiedData unifiedData;
848 int32_t status = store->DeleteLocal(std::to_string(accessTokenIDEx));
849 if (status != E_OK) {
850 ZLOGE("Store DeleteLocal failed:%{public}s, status:%{public}d", intention.c_str(), status);
851 HandleDbError(intention, status);
852 return E_DB_ERROR;
853 }
854 return E_OK;
855 }
856
OnInitialize()857 int32_t UdmfServiceImpl::OnInitialize()
858 {
859 ZLOGD("start");
860 Status status = LifeCycleManager::GetInstance().OnStart();
861 if (status != E_OK) {
862 ZLOGE("OnStart execute failed, status: %{public}d", status);
863 }
864 status = LifeCycleManager::GetInstance().StartLifeCycleTimer();
865 if (status != E_OK) {
866 ZLOGE("StartLifeCycleTimer start failed, status: %{public}d", status);
867 }
868 return DistributedData::FeatureSystem::STUB_SUCCESS;
869 }
870
QueryDataCommon(const QueryOption & query,std::vector<UnifiedData> & dataSet,std::shared_ptr<Store> & store)871 int32_t UdmfServiceImpl::QueryDataCommon(
872 const QueryOption &query, std::vector<UnifiedData> &dataSet, std::shared_ptr<Store> &store)
873 {
874 UnifiedKey key(query.key);
875 if (!key.IsValid() && !key.key.empty()) {
876 ZLOGE("invalid key, query.key: %{public}s", query.key.c_str());
877 return E_INVALID_PARAMETERS;
878 }
879 std::string intention = FindIntentionMap(query.intention);
880 if (!IsValidOptionsNonDrag(key, intention)) {
881 ZLOGE("Unified key: %{public}s and intention: %{public}s is invalid.", query.key.c_str(), intention.c_str());
882 return E_INVALID_PARAMETERS;
883 }
884 std::string dataPrefix;
885 if (key.key.empty()) {
886 dataPrefix = DATA_PREFIX + intention;
887 } else {
888 dataPrefix = UnifiedKey(key.key).GetKeyCommonPrefix();
889 intention = key.intention;
890 }
891 ZLOGD("dataPrefix = %{public}s, intention: %{public}s.", dataPrefix.c_str(), intention.c_str());
892 store = StoreCache::GetInstance().GetStore(intention);
893 if (store == nullptr) {
894 ZLOGE("Get store failed:%{public}s", intention.c_str());
895 return E_DB_ERROR;
896 }
897 int32_t status = store->GetBatchData(dataPrefix, dataSet);
898 if (status != E_OK) {
899 ZLOGE("Get dataSet failed, dataPrefix: %{public}s, status:%{public}d.", dataPrefix.c_str(), status);
900 HandleDbError(intention, status);
901 return E_DB_ERROR;
902 }
903 return E_OK;
904 }
905
OnBind(const BindInfo & bindInfo)906 int32_t UdmfServiceImpl::OnBind(const BindInfo &bindInfo)
907 {
908 executors_ = bindInfo.executors;
909 StoreCache::GetInstance().SetThreadPool(bindInfo.executors);
910 LifeCycleManager::GetInstance().SetThreadPool(bindInfo.executors);
911 return 0;
912 }
913
ObtainAsynProcess(AsyncProcessInfo & processInfo)914 int32_t UdmfServiceImpl::ObtainAsynProcess(AsyncProcessInfo &processInfo)
915 {
916 if (processInfo.businessUdKey.empty()) {
917 return E_INVALID_PARAMETERS;
918 }
919 std::lock_guard<std::mutex> lock(mutex_);
920 if (asyncProcessInfoMap_.empty()) {
921 processInfo.syncStatus = AsyncTaskStatus::ASYNC_SUCCESS;
922 processInfo.srcDevName = "Local";
923 return E_OK;
924 }
925 auto it = asyncProcessInfoMap_.find(processInfo.businessUdKey);
926 if (it == asyncProcessInfoMap_.end()) {
927 processInfo.syncStatus = AsyncTaskStatus::ASYNC_SUCCESS;
928 processInfo.srcDevName = "Local";
929 return E_OK;
930 }
931 auto asyncProcessInfo = asyncProcessInfoMap_.at(processInfo.businessUdKey);
932 processInfo.syncStatus = asyncProcessInfo.syncStatus;
933 processInfo.srcDevName = asyncProcessInfo.srcDevName;
934 return E_OK;
935 }
936
ClearAsynProcessByKey(const std::string & businessUdKey)937 int32_t UdmfServiceImpl::ClearAsynProcessByKey(const std::string & businessUdKey)
938 {
939 ZLOGI("ClearAsynProcessByKey begin.");
940 std::lock_guard<std::mutex> lock(mutex_);
941 if (asyncProcessInfoMap_.find(businessUdKey) == asyncProcessInfoMap_.end()) {
942 return E_OK;
943 }
944 asyncProcessInfoMap_.erase(businessUdKey);
945 return E_OK;
946 }
947
ResolveAutoLaunch(const std::string & identifier,DBLaunchParam & param)948 int32_t UdmfServiceImpl::ResolveAutoLaunch(const std::string &identifier, DBLaunchParam ¶m)
949 {
950 ZLOGI("user:%{public}s appId:%{public}s storeId:%{public}s identifier:%{public}s", param.userId.c_str(),
951 param.appId.c_str(), DistributedData::Anonymous::Change(param.storeId).c_str(),
952 DistributedData::Anonymous::Change(identifier).c_str());
953
954 std::vector<StoreMetaData> metaData;
955 auto prefix = StoreMetaData::GetPrefix({ DmAdapter::GetInstance().GetLocalDevice().uuid });
956 if (!DistributedData::MetaDataManager::GetInstance().LoadMeta(prefix, metaData)) {
957 ZLOGE("no meta data appId:%{public}s", param.appId.c_str());
958 return E_NOT_FOUND;
959 }
960
961 for (const auto &storeMeta : metaData) {
962 if (storeMeta.storeType < StoreMetaData::StoreType::STORE_KV_BEGIN ||
963 storeMeta.storeType > StoreMetaData::StoreType::STORE_KV_END ||
964 storeMeta.appId != Bootstrap::GetInstance().GetProcessLabel()) {
965 continue;
966 }
967 auto identifierTag = DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier("", storeMeta.appId,
968 storeMeta.storeId, true);
969 if (identifier != identifierTag) {
970 continue;
971 }
972 auto store = StoreCache::GetInstance().GetStore(storeMeta.storeId);
973 if (store == nullptr) {
974 ZLOGE("GetStore fail, storeId:%{public}s", Anonymous::Change(storeMeta.storeId).c_str());
975 continue;
976 }
977 ZLOGI("storeId:%{public}s,appId:%{public}s,user:%{public}s", Anonymous::Change(storeMeta.storeId).c_str(),
978 storeMeta.appId.c_str(), storeMeta.user.c_str());
979 return E_OK;
980 }
981 return E_OK;
982 }
983
VerifyPermission(const std::string & permission,uint32_t callerTokenId)984 bool UdmfServiceImpl::VerifyPermission(const std::string &permission, uint32_t callerTokenId)
985 {
986 if (permission.empty()) {
987 ZLOGE("VerifyPermission failed, Permission is empty.");
988 return false;
989 }
990 int status = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerTokenId, permission);
991 if (status != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
992 ZLOGE("Permission denied. status:%{public}d, token:0x%{public}x, permission:%{public}s",
993 status, callerTokenId, permission.c_str());
994 return false;
995 }
996 return true;
997 }
998
HasDatahubPriviledge(const std::string & bundleName)999 bool UdmfServiceImpl::HasDatahubPriviledge(const std::string &bundleName)
1000 {
1001 uint64_t accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID();
1002 bool isSystemApp = TokenIdKit::IsSystemAppByFullTokenID(accessTokenIDEx);
1003 return std::find(std::begin(HAP_LIST), std::end(HAP_LIST), bundleName) != std::end(HAP_LIST) && isSystemApp;
1004 }
1005
RegisterAsyncProcessInfo(const std::string & businessUdKey)1006 void UdmfServiceImpl::RegisterAsyncProcessInfo(const std::string &businessUdKey)
1007 {
1008 AsyncProcessInfo info;
1009 std::lock_guard<std::mutex> lock(mutex_);
1010 asyncProcessInfoMap_.insert_or_assign(businessUdKey, std::move(info));
1011 }
1012
OnUserChange(uint32_t code,const std::string & user,const std::string & account)1013 int32_t UdmfServiceImpl::OnUserChange(uint32_t code, const std::string &user, const std::string &account)
1014 {
1015 ZLOGI("user change, code:%{public}u, user:%{public}s", code, user.c_str());
1016 if (code == static_cast<uint32_t>(DistributedData::AccountStatus::DEVICE_ACCOUNT_STOPPING)
1017 || code == static_cast<uint32_t>(DistributedData::AccountStatus::DEVICE_ACCOUNT_STOPPED)
1018 || code == static_cast<uint32_t>(DistributedData::AccountStatus::DEVICE_ACCOUNT_SWITCHED)) {
1019 StoreCache::GetInstance().CloseStores();
1020 }
1021 return Feature::OnUserChange(code, user, account);
1022 }
1023
TransferToEntriesIfNeed(const QueryOption & query,UnifiedData & unifiedData)1024 void UdmfServiceImpl::TransferToEntriesIfNeed(const QueryOption &query, UnifiedData &unifiedData)
1025 {
1026 if (unifiedData.IsNeedTransferToEntries() && IsNeedTransferDeviceType(query)) {
1027 unifiedData.ConvertRecordsToEntries();
1028 }
1029 }
1030
IsNeedTransferDeviceType(const QueryOption & query)1031 bool UdmfServiceImpl::IsNeedTransferDeviceType(const QueryOption &query)
1032 {
1033 auto deviceInfo = DmAdapter::GetInstance().GetLocalDevice();
1034 if (deviceInfo.deviceType != DEVICE_TYPE_PC && deviceInfo.deviceType != DEVICE_TYPE_PAD
1035 && deviceInfo.deviceType != DEVICE_TYPE_2IN1) {
1036 return false;
1037 }
1038 auto bundleManager = PreProcessUtils::GetBundleMgr();
1039 if (bundleManager == nullptr) {
1040 ZLOGE("Failed to get bundle manager");
1041 return false;
1042 }
1043 std::string bundleName;
1044 PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName);
1045 int32_t userId = DistributedData::AccountDelegate::GetInstance()->GetUserByToken(
1046 IPCSkeleton::GetCallingFullTokenID());
1047 AppExecFwk::BundleInfo bundleInfo;
1048 bundleManager->GetBundleInfoV9(bundleName, static_cast<int32_t>(
1049 AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE), bundleInfo, userId);
1050 for (const auto &hapModuleInfo : bundleInfo.hapModuleInfos) {
1051 if (std::find(hapModuleInfo.deviceTypes.begin(), hapModuleInfo.deviceTypes.end(),
1052 DEVICE_PHONE_TAG) == hapModuleInfo.deviceTypes.end()
1053 && std::find(hapModuleInfo.deviceTypes.begin(), hapModuleInfo.deviceTypes.end(),
1054 DEVICE_DEFAULT_TAG) == hapModuleInfo.deviceTypes.end()
1055 && std::find(hapModuleInfo.deviceTypes.begin(), hapModuleInfo.deviceTypes.end(),
1056 DEVICE_2IN1_TAG) != hapModuleInfo.deviceTypes.end()) {
1057 return true;
1058 }
1059 }
1060 return false;
1061 }
1062
CheckAddPrivilegePermission(UnifiedKey & key,std::string & processName,const QueryOption & query)1063 int32_t UdmfServiceImpl::CheckAddPrivilegePermission(UnifiedKey &key,
1064 std::string &processName, const QueryOption &query)
1065 {
1066 if (IsFileMangerIntention(key.intention)) {
1067 if (IsFileMangerSa()) {
1068 return E_OK;
1069 }
1070 std::string intention = FindIntentionMap(query.intention);
1071 if (!intention.empty() && key.intention != intention) {
1072 ZLOGE("Query.intention no not equal to key.intention");
1073 return E_INVALID_PARAMETERS;
1074 }
1075 return E_OK;
1076 }
1077 if (key.intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) {
1078 if (find(DRAG_AUTHORIZED_PROCESSES, std::end(DRAG_AUTHORIZED_PROCESSES), processName) ==
1079 std::end(DRAG_AUTHORIZED_PROCESSES)) {
1080 ZLOGE("Process:%{public}s lacks permission for intention:drag", processName.c_str());
1081 return E_NO_PERMISSION;
1082 }
1083 return E_OK;
1084 }
1085 ZLOGE("Check addPrivilege permission is faild.");
1086 return E_NO_PERMISSION;
1087 }
1088
IsFileMangerSa()1089 bool UdmfServiceImpl::IsFileMangerSa()
1090 {
1091 if (IPCSkeleton::GetCallingUid() == FOUNDATION_UID) {
1092 return true;
1093 }
1094 ZLOGE("Caller no permission");
1095 return false;
1096 }
1097
ProcessData(const QueryOption & query,std::vector<UnifiedData> & dataSet)1098 int32_t UdmfServiceImpl::ProcessData(const QueryOption &query, std::vector<UnifiedData> &dataSet)
1099 {
1100 UnifiedKey key(query.key);
1101 if (!key.key.empty() && !key.IsValid()) {
1102 ZLOGE("invalid key, query.key: %{public}s", query.key.c_str());
1103 return E_INVALID_PARAMETERS;
1104 }
1105 std::string intention = FindIntentionMap(query.intention);
1106 if (intention == UD_INTENTION_MAP.at(UD_INTENTION_DATA_HUB) ||
1107 key.intention == UD_INTENTION_MAP.at(UD_INTENTION_DATA_HUB)) {
1108 return E_OK;
1109 }
1110 CheckerManager::CheckInfo info;
1111 info.tokenId = query.tokenId;
1112 for (auto &data : dataSet) {
1113 auto ret = VerifyIntentionPermission(query, data, key, info);
1114 if (ret != E_OK) {
1115 ZLOGE("Verify intention permission is faild:%{public}d", ret);
1116 return ret;
1117 }
1118 }
1119 return E_OK;
1120 }
1121
VerifyIntentionPermission(const QueryOption & query,UnifiedData & data,UnifiedKey & key,CheckerManager::CheckInfo & info)1122 int32_t UdmfServiceImpl::VerifyIntentionPermission(const QueryOption &query,
1123 UnifiedData &data, UnifiedKey &key, CheckerManager::CheckInfo &info)
1124 {
1125 std::shared_ptr<Runtime> runtime = data.GetRuntime();
1126 if (runtime == nullptr) {
1127 ZLOGE("runtime is nullptr.");
1128 return E_DB_ERROR;
1129 }
1130 if (!CheckerManager::GetInstance().IsValid(runtime->privileges, info)) {
1131 ZLOGE("Query no permission.");
1132 return E_NO_PERMISSION;
1133 }
1134 if (!IsReadAndKeep(runtime->privileges, query)) {
1135 if (LifeCycleManager::GetInstance().OnGot(key) != E_OK) {
1136 ZLOGE("Remove data failed:%{public}s", key.intention.c_str());
1137 return E_DB_ERROR;
1138 }
1139 }
1140 return E_OK;
1141 }
1142
IsFileMangerIntention(const std::string & intention)1143 bool UdmfServiceImpl::IsFileMangerIntention(const std::string &intention)
1144 {
1145 Intention optionIntention = UnifiedDataUtils::GetIntentionByString(intention);
1146 if (optionIntention == UD_INTENTION_SYSTEM_SHARE ||
1147 optionIntention == UD_INTENTION_MENU ||
1148 optionIntention == UD_INTENTION_PICKER) {
1149 return true;
1150 }
1151 return false;
1152 }
1153
FindIntentionMap(const Intention & queryIntention)1154 std::string UdmfServiceImpl::FindIntentionMap(const Intention &queryIntention)
1155 {
1156 auto find = UD_INTENTION_MAP.find(queryIntention);
1157 return find == UD_INTENTION_MAP.end() ? "" : find->second;
1158 }
1159
IsValidOptionsNonDrag(UnifiedKey & key,const std::string & intention)1160 bool UdmfServiceImpl::IsValidOptionsNonDrag(UnifiedKey &key, const std::string &intention)
1161 {
1162 if (UnifiedDataUtils::IsValidOptions(key, intention)) {
1163 return !key.key.empty() || intention == UD_INTENTION_MAP.at(Intention::UD_INTENTION_DATA_HUB);
1164 }
1165 return false;
1166 }
1167
SetDelayInfo(const DataLoadInfo & dataLoadInfo,sptr<IRemoteObject> iUdmfNotifier,std::string & key)1168 int32_t UdmfServiceImpl::SetDelayInfo(const DataLoadInfo &dataLoadInfo, sptr<IRemoteObject> iUdmfNotifier,
1169 std::string &key)
1170 {
1171 std::string bundleName;
1172 std::string specificBundleName;
1173 auto tokenId = static_cast<uint32_t>(IPCSkeleton::GetCallingTokenID());
1174 if (!PreProcessUtils::GetSpecificBundleNameByTokenId(tokenId, specificBundleName, bundleName)) {
1175 ZLOGE("GetSpecificBundleNameByTokenId failed, tokenid:%{public}u", tokenId);
1176 return E_ERROR;
1177 }
1178 UnifiedKey udkey(UD_INTENTION_MAP.at(UD_INTENTION_DRAG), specificBundleName, dataLoadInfo.sequenceKey);
1179 key = udkey.GetUnifiedKey();
1180 dataLoadCallback_.Insert(key, iface_cast<UdmfNotifierProxy>(iUdmfNotifier));
1181
1182 auto store = StoreCache::GetInstance().GetStore(UD_INTENTION_MAP.at(UD_INTENTION_DRAG));
1183 if (store == nullptr) {
1184 ZLOGE("Get store failed:%{public}s", key.c_str());
1185 return E_DB_ERROR;
1186 }
1187
1188 Summary summary;
1189 UnifiedDataHelper::GetSummaryFromLoadInfo(dataLoadInfo, summary);
1190 int32_t status = store->PutSummary(udkey, summary);
1191 if (status != E_OK) {
1192 ZLOGE("Put summary failed:%{public}s, status:%{public}d", key.c_str(), status);
1193 HandleDbError(UD_INTENTION_MAP.at(UD_INTENTION_DRAG), status);
1194 return E_DB_ERROR;
1195 }
1196 return E_OK;
1197 }
1198
PushDelayData(const std::string & key,UnifiedData & unifiedData)1199 int32_t UdmfServiceImpl::PushDelayData(const std::string &key, UnifiedData &unifiedData)
1200 {
1201 CustomOption option;
1202 option.intention = UD_INTENTION_DRAG;
1203 option.tokenId = static_cast<uint32_t>(IPCSkeleton::GetCallingTokenID());
1204 if (PreProcessUtils::FillRuntimeInfo(unifiedData, option) != E_OK) {
1205 ZLOGE("Imputation failed");
1206 return E_ERROR;
1207 }
1208 int32_t ret = PreProcessUtils::SetRemoteUri(option.tokenId, unifiedData);
1209 if (ret != E_OK) {
1210 ZLOGW("SetRemoteUri failed, ret:%{public}d, key:%{public}s.", ret, key.c_str());
1211 }
1212
1213 auto it = delayDataCallback_.Find(key);
1214 if (!it.first) {
1215 ZLOGE("DelayData callback no exist, key:%{public}s", key.c_str());
1216 return E_ERROR;
1217 }
1218 QueryOption query;
1219 query.tokenId = it.second.tokenId;
1220 query.key = key;
1221 if (option.tokenId != query.tokenId && !IsPermissionInCache(query)) {
1222 ZLOGE("No permission");
1223 return E_NO_PERMISSION;
1224 }
1225 ret = ProcessUri(query, unifiedData);
1226 if (ret != E_OK) {
1227 ZLOGE("ProcessUri failed:%{public}d", ret);
1228 return E_NO_PERMISSION;
1229 }
1230 {
1231 std::lock_guard<std::recursive_mutex> lock(cacheMutex_);
1232 privilegeCache_.erase(key);
1233 }
1234 PreProcessUtils::SetRemoteData(unifiedData);
1235
1236 TransferToEntriesIfNeed(query, unifiedData);
1237 return HandleDelayDataCallback(it.second, unifiedData, key);
1238 }
1239
HandleDelayDataCallback(DelayGetDataInfo & delayGetDataInfo,UnifiedData & unifiedData,const std::string & key)1240 int32_t UdmfServiceImpl::HandleDelayDataCallback(DelayGetDataInfo &delayGetDataInfo, UnifiedData &unifiedData,
1241 const std::string &key)
1242 {
1243 auto callback = iface_cast<DelayDataCallbackProxy>(delayGetDataInfo.dataCallback);
1244 if (callback == nullptr) {
1245 ZLOGE("Delay data callback is null, key:%{public}s", key.c_str());
1246 return E_ERROR;
1247 }
1248 callback->DelayDataCallback(key, unifiedData);
1249 delayDataCallback_.Erase(key);
1250 return E_OK;
1251 }
1252
GetDataIfAvailable(const std::string & key,const DataLoadInfo & dataLoadInfo,sptr<IRemoteObject> iUdmfNotifier,std::shared_ptr<UnifiedData> unifiedData)1253 int32_t UdmfServiceImpl::GetDataIfAvailable(const std::string &key, const DataLoadInfo &dataLoadInfo,
1254 sptr<IRemoteObject> iUdmfNotifier, std::shared_ptr<UnifiedData> unifiedData)
1255 {
1256 ZLOGD("start");
1257 QueryOption query;
1258 query.tokenId = static_cast<uint32_t>(IPCSkeleton::GetCallingTokenID());
1259 query.key = key;
1260 if (unifiedData == nullptr) {
1261 ZLOGE("Data is null, key:%{public}s", key.c_str());
1262 return E_ERROR;
1263 }
1264 auto status = RetrieveData(query, *unifiedData);
1265 if (status == E_OK) {
1266 return E_OK;
1267 }
1268 if (status != E_NOT_FOUND) {
1269 ZLOGE("Retrieve data failed, key:%{public}s", key.c_str());
1270 return status;
1271 }
1272 DelayGetDataInfo delayGetDataInfo;
1273 delayGetDataInfo.dataCallback = iUdmfNotifier;
1274 delayGetDataInfo.tokenId = static_cast<uint32_t>(IPCSkeleton::GetCallingTokenID());
1275 delayDataCallback_.InsertOrAssign(key, std::move(delayGetDataInfo));
1276
1277 auto it = dataLoadCallback_.Find(key);
1278 if (!it.first) {
1279 ZLOGE("DataLoad callback no exist, key:%{public}s", key.c_str());
1280 return E_ERROR;
1281 }
1282 it.second->HandleDelayObserver(key, dataLoadInfo);
1283 dataLoadCallback_.Erase(key);
1284 return E_OK;
1285 }
1286
IsValidInput(const QueryOption & query,UnifiedData & unifiedData,UnifiedKey & key)1287 bool UdmfServiceImpl::IsValidInput(const QueryOption &query, UnifiedData &unifiedData, UnifiedKey &key)
1288 {
1289 if (!unifiedData.IsValid() || !key.IsValid()) {
1290 ZLOGE("Data or key is invalid, key = %{public}s", query.key.c_str());
1291 return false;
1292 }
1293 std::string intention = FindIntentionMap(query.intention);
1294 if (!IsValidOptionsNonDrag(key, intention) || key.intention != UD_INTENTION_MAP.at(UD_INTENTION_DATA_HUB)) {
1295 ZLOGE("Invalid params: key.intention = %{public}s, intention = %{public}s",
1296 key.intention.c_str(), intention.c_str());
1297 return false;
1298 }
1299 return true;
1300 }
1301
CloseStoreWhenCorrupted(const std::string & intention,int32_t status)1302 void UdmfServiceImpl::CloseStoreWhenCorrupted(const std::string &intention, int32_t status)
1303 {
1304 if (status == E_DB_CORRUPTED) {
1305 ZLOGE("Kv database corrupted, start to remove store");
1306 StoreCache::GetInstance().RemoveStore(intention);
1307 }
1308 }
1309
HandleDbError(const std::string & intention,int32_t & status)1310 void UdmfServiceImpl::HandleDbError(const std::string &intention, int32_t &status)
1311 {
1312 CloseStoreWhenCorrupted(intention, status);
1313 if (status == E_DB_CORRUPTED) {
1314 // reset status to E_DB_ERROR
1315 status = E_DB_ERROR;
1316 }
1317 }
1318
BuildMeta(const std::string & storeId,int userId)1319 StoreMetaData UdmfServiceImpl::BuildMeta(const std::string &storeId, int userId)
1320 {
1321 StoreMetaData meta;
1322 meta.user = std::to_string(userId);
1323 meta.storeId = storeId;
1324 meta.bundleName = Bootstrap::GetInstance().GetProcessLabel();
1325 return meta;
1326 }
1327
ProcessResult(const std::map<std::string,int32_t> & results)1328 std::vector<std::string> UdmfServiceImpl::ProcessResult(const std::map<std::string, int32_t> &results)
1329 {
1330 std::vector<std::string> devices;
1331 for (const auto &[uuid, status] : results) {
1332 if (static_cast<DistributedDB::DBStatus>(status) == DistributedDB::DBStatus::OK) {
1333 DeviceMatrix::GetInstance().OnExchanged(uuid, DeviceMatrix::META_STORE_MASK);
1334 devices.emplace_back(uuid);
1335 }
1336 }
1337 ZLOGI("Meta sync finish, total size:%{public}zu, success size:%{public}zu", results.size(), devices.size());
1338 return devices;
1339 }
1340 } // namespace UDMF
1341 } // namespace OHOS