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