• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
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 &param)
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