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 "file.h"
29 #include "lifecycle/lifecycle_manager.h"
30 #include "log_print.h"
31 #include "preprocess_utils.h"
32 #include "reporter.h"
33 #include "uri_permission_manager.h"
34 #include "uri.h"
35 #include "udmf_conversion.h"
36 #include "udmf_radar_reporter.h"
37 #include "securec.h"
38 #include "unified_types.h"
39 #include "device_manager_adapter.h"
40 #include "store_account_observer.h"
41 
42 
43 namespace OHOS {
44 namespace UDMF {
45 using namespace Security::AccessToken;
46 using FeatureSystem = DistributedData::FeatureSystem;
47 using UdmfBehaviourMsg = OHOS::DistributedDataDfx::UdmfBehaviourMsg;
48 using Reporter = OHOS::DistributedDataDfx::Reporter;
49 using namespace RadarReporter;
50 using namespace DistributedKv;
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 __attribute__((used)) UdmfServiceImpl::Factory UdmfServiceImpl::factory_;
Factory()56 UdmfServiceImpl::Factory::Factory()
57 {
58     ZLOGI("Register udmf creator!");
59     FeatureSystem::GetInstance().RegisterCreator("udmf", [this]() {
60         if (product_ == nullptr) {
61             product_ = std::make_shared<UdmfServiceImpl>();
62         }
63         return product_;
64     }, FeatureSystem::BIND_NOW);
65     auto observer = std::make_shared<RuntimeStoreAccountObserver>();
66     DistributedKv::AccountDelegate::GetInstance()->Subscribe(observer);
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 
99     for (const auto &record : unifiedData.GetRecords()) {
100         for (const auto &type : record->GetUtdIds()) {
101             types.append("-").append(type);
102         }
103     }
104     msg.dataType = types;
105     msg.dataSize = unifiedData.GetSize();
106     Reporter::GetInstance()->BehaviourReporter()->UDMFReport(msg);
107     return res;
108 }
109 
SaveData(CustomOption &option, UnifiedData &unifiedData, std::string &key)110 int32_t UdmfServiceImpl::SaveData(CustomOption &option, UnifiedData &unifiedData, std::string &key)
111 {
112     if (!unifiedData.IsValid()) {
113         ZLOGE("UnifiedData is invalid.");
114         return E_INVALID_PARAMETERS;
115     }
116 
117     if (!UnifiedDataUtils::IsValidIntention(option.intention)) {
118         ZLOGE("Invalid parameters intention: %{public}d.", option.intention);
119         return E_INVALID_PARAMETERS;
120     }
121 
122     // imput runtime info before put it into store and save one privilege
123     if (PreProcessUtils::RuntimeDataImputation(unifiedData, option) != E_OK) {
124         ZLOGE("Imputation failed");
125         return E_ERROR;
126     }
127 
128     std::string intention = unifiedData.GetRuntime()->key.intention;
129     if (intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) {
130         int32_t ret = PreProcessUtils::SetRemoteUri(option.tokenId, unifiedData);
131         if (ret != E_OK) {
132             ZLOGE("SetRemoteUri failed, ret: %{public}d, bundleName:%{public}s.", ret,
133                   unifiedData.GetRuntime()->createPackage.c_str());
134             return ret;
135         }
136     }
137 
138     for (const auto &record : unifiedData.GetRecords()) {
139         record->SetUid(PreProcessUtils::GenerateId());
140     }
141 
142     auto store = StoreCache::GetInstance().GetStore(intention);
143     if (store == nullptr) {
144         ZLOGE("Get store failed, intention: %{public}s.", intention.c_str());
145         return E_DB_ERROR;
146     }
147 
148     if (!UnifiedDataUtils::IsPersist(intention) && store->Clear() != E_OK) {
149         ZLOGE("Clear store failed, intention: %{public}s.", intention.c_str());
150         return E_DB_ERROR;
151     }
152 
153     UdmfConversion::InitValueObject(unifiedData);
154     if (store->Put(unifiedData) != E_OK) {
155         ZLOGE("Put unified data failed, intention: %{public}s.", intention.c_str());
156         return E_DB_ERROR;
157     }
158     key = unifiedData.GetRuntime()->key.GetUnifiedKey();
159     ZLOGD("Put unified data successful, key: %{public}s.", key.c_str());
160     return E_OK;
161 }
162 
GetData(const QueryOption &query, UnifiedData &unifiedData)163 int32_t UdmfServiceImpl::GetData(const QueryOption &query, UnifiedData &unifiedData)
164 {
165     ZLOGD("start");
166     int32_t res = E_OK;
167     UdmfBehaviourMsg msg;
168     std::string types;
169     auto find = UD_INTENTION_MAP.find(query.intention);
170     msg.channel = find == UD_INTENTION_MAP.end() ? "invalid" : find->second;
171     msg.operation = "insert";
172     std::string bundleName;
173     if (!PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName)) {
174         msg.appId = "unknown";
175         res = E_ERROR;
176     } else {
177         msg.appId = bundleName;
178         res = RetrieveData(query, unifiedData);
179     }
180     auto errFind = ERROR_MAP.find(res);
181     msg.result = errFind == ERROR_MAP.end() ? "E_ERROR" : errFind->second;
182     for (const auto &record : unifiedData.GetRecords()) {
183         for (const auto &type : record->GetUtdIds()) {
184             types.append("-").append(type);
185         }
186     }
187     msg.dataType = types;
188     msg.dataSize = unifiedData.GetSize();
189     Reporter::GetInstance()->BehaviourReporter()->UDMFReport(msg);
190     return res;
191 }
192 
RetrieveData(const QueryOption &query, UnifiedData &unifiedData)193 int32_t UdmfServiceImpl::RetrieveData(const QueryOption &query, UnifiedData &unifiedData)
194 {
195     UnifiedKey key(query.key);
196     if (!key.IsValid()) {
197         ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str());
198         return E_INVALID_PARAMETERS;
199     }
200     auto store = StoreCache::GetInstance().GetStore(key.intention);
201     if (store == nullptr) {
202         ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str());
203         return E_DB_ERROR;
204     }
205     int32_t res = store->Get(query.key, unifiedData);
206     if (res != E_OK) {
207         ZLOGE("Get data from store failed, res: %{public}d, key: %{public}s.", res, query.key.c_str());
208         return res;
209     }
210 
211     if (!unifiedData.IsComplete()) {
212         ZLOGE("Get data from DB is incomplete, key: %{public}s.", query.key.c_str());
213         return E_NOT_FOUND;
214     }
215 
216     CheckerManager::CheckInfo info;
217     info.tokenId = query.tokenId;
218     std::shared_ptr<Runtime> runtime = unifiedData.GetRuntime();
219     if (runtime == nullptr) {
220         return E_DB_ERROR;
221     }
222     if (!CheckerManager::GetInstance().IsValid(runtime->privileges, info) && !IsPermissionInCache(query)) {
223         RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
224             BizScene::GET_DATA, GetDataStage::VERIFY_PRIVILEGE, StageRes::FAILED, E_NO_PERMISSION);
225         return E_NO_PERMISSION;
226     }
227 
228     if (key.intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) {
229         int32_t ret = ProcessUri(query, unifiedData);
230         if (ret != E_OK) {
231             ZLOGE("ProcessUri failed. ret=%{public}d", ret);
232             return E_NO_PERMISSION;
233         }
234     }
235     if (!IsReadAndKeep(runtime->privileges, query)) {
236         if (LifeCycleManager::GetInstance().OnGot(key) != E_OK) {
237             ZLOGE("Remove data failed, intention: %{public}s.", key.intention.c_str());
238             return E_DB_ERROR;
239         }
240     }
241 
242     privilegeCache_.erase(query.key);
243 
244     PreProcessUtils::SetRemoteData(unifiedData);
245     return E_OK;
246 }
247 
IsPermissionInCache(const QueryOption &query)248 bool UdmfServiceImpl::IsPermissionInCache(const QueryOption &query)
249 {
250     auto iter = privilegeCache_.find(query.key);
251     if (iter != privilegeCache_.end() && iter->second.tokenId == query.tokenId) {
252         return true;
253     }
254     return false;
255 }
256 
IsReadAndKeep(const std::vector<Privilege> &privileges, const QueryOption &query)257 bool UdmfServiceImpl::IsReadAndKeep(const std::vector<Privilege> &privileges, const QueryOption &query)
258 {
259     for (const auto &privilege : privileges) {
260         if (privilege.tokenId == query.tokenId && privilege.readPermission == PRIVILEGE_READ_AND_KEEP) {
261             return true;
262         }
263     }
264 
265     auto iter = privilegeCache_.find(query.key);
266     if (iter != privilegeCache_.end() && iter->second.tokenId == query.tokenId &&
267         iter->second.readPermission == PRIVILEGE_READ_AND_KEEP) {
268         return true;
269     }
270     return false;
271 }
272 
ProcessUri(const QueryOption &query, UnifiedData &unifiedData)273 int32_t UdmfServiceImpl::ProcessUri(const QueryOption &query, UnifiedData &unifiedData)
274 {
275     std::string localDeviceId = PreProcessUtils::GetLocalDeviceId();
276     auto records = unifiedData.GetRecords();
277     if (unifiedData.GetRuntime() == nullptr) {
278         return E_DB_ERROR;
279     }
280     std::string sourceDeviceId = unifiedData.GetRuntime()->deviceId;
281     if (localDeviceId != sourceDeviceId) {
282         SetRemoteUri(query, records);
283     }
284     std::string bundleName;
285     if (!PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName)) {
286         ZLOGE("GetHapBundleNameByToken fail, key=%{public}s, tokenId=%{private}d.", query.key.c_str(), query.tokenId);
287         return E_ERROR;
288     }
289     if (localDeviceId == sourceDeviceId && query.tokenId == unifiedData.GetRuntime()->tokenId) {
290         ZLOGW("No need to grant uri permissions, queryKey=%{public}s.", query.key.c_str());
291         return E_OK;
292     }
293     std::vector<Uri> allUri;
294     for (auto record : records) {
295         if (record != nullptr && PreProcessUtils::IsFileType(record->GetType())) {
296             auto file = static_cast<File *>(record.get());
297             if (file->GetUri().empty()) {
298                 ZLOGW("Get uri is empty, key=%{public}s.", query.key.c_str());
299                 continue;
300             }
301             Uri uri(file->GetUri());
302             std::string scheme = uri.GetScheme();
303             std::transform(scheme.begin(), scheme.end(), scheme.begin(), ::tolower);
304             if (uri.GetAuthority().empty() || scheme != FILE_SCHEME) {
305                 ZLOGW("Get authority is empty or uri scheme not equals to file, key=%{public}s.", query.key.c_str());
306                 continue;
307             }
308             allUri.push_back(uri);
309         }
310     }
311     asyncProcessInfo_.permStatus = ASYNC_RUNNING;
312     asyncProcessInfo_.permTotal = allUri.size();
313     if (UriPermissionManager::GetInstance().GrantUriPermission(allUri, query.tokenId, query.key,
314         asyncProcessInfo_.permFnished) != E_OK) {
315         RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
316             BizScene::GET_DATA, GetDataStage::GRANT_URI_PERMISSION, StageRes::FAILED, E_NO_PERMISSION);
317         ZLOGE("GrantUriPermission fail, bundleName=%{public}s, key=%{public}s.",
318               bundleName.c_str(), query.key.c_str());
319         return E_NO_PERMISSION;
320     }
321     return E_OK;
322 }
323 
SetRemoteUri(const QueryOption &query, std::vector<std::shared_ptr<UnifiedRecord>> &records)324 void UdmfServiceImpl::SetRemoteUri(const QueryOption &query, std::vector<std::shared_ptr<UnifiedRecord>> &records)
325 {
326     for (auto record : records) {
327         if (record != nullptr && PreProcessUtils::IsFileType(record->GetType())) {
328             auto file = static_cast<File *>(record.get());
329             std::string remoteUri = file->GetRemoteUri();
330             if (remoteUri.empty()) {
331                 ZLOGW("Get remoteUri is empyt, key=%{public}s.", query.key.c_str());
332                 continue;
333             }
334             file->SetUri(remoteUri); // cross dev, need dis path.
335         }
336     }
337 }
338 
GetBatchData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet)339 int32_t UdmfServiceImpl::GetBatchData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet)
340 {
341     ZLOGD("start");
342     std::vector<UnifiedData> dataSet;
343     std::shared_ptr<Store> store;
344     auto status = QueryDataCommon(query, dataSet, store);
345     if (status != E_OK) {
346         ZLOGE("QueryDataCommon failed.");
347         return status;
348     }
349     if (dataSet.empty()) {
350         ZLOGW("DataSet has no data, key: %{public}s, intention: %{public}d.", query.key.c_str(), query.intention);
351         return E_OK;
352     }
353     for (auto &data : dataSet) {
354         PreProcessUtils::SetRemoteData(data);
355         unifiedDataSet.push_back(data);
356     }
357     return E_OK;
358 }
359 
UpdateData(const QueryOption &query, UnifiedData &unifiedData)360 int32_t UdmfServiceImpl::UpdateData(const QueryOption &query, UnifiedData &unifiedData)
361 {
362     UnifiedKey key(query.key);
363     if (!unifiedData.IsValid() || !key.IsValid()) {
364         ZLOGE("data is invalid, or key is invalid. key=%{public}s.", query.key.c_str());
365         return E_INVALID_PARAMETERS;
366     }
367     std::string bundleName;
368     PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName);
369     if (key.bundleName != bundleName) {
370         ZLOGE("update data failed by %{public}s, key: %{public}s.", bundleName.c_str(), query.key.c_str());
371         return E_INVALID_PARAMETERS;
372     }
373     auto store = StoreCache::GetInstance().GetStore(key.intention);
374     if (store == nullptr) {
375         ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str());
376         return E_DB_ERROR;
377     }
378     UnifiedData data;
379     int32_t res = store->Get(query.key, data);
380     if (res != E_OK) {
381         ZLOGE("Get data from store failed, intention: %{public}s.", key.intention.c_str());
382         return res;
383     }
384     if (data.IsEmpty()) {
385         ZLOGE("Invalid parameter, unified data has no record; intention: %{public}s.", key.intention.c_str());
386         return E_INVALID_PARAMETERS;
387     }
388     std::shared_ptr<Runtime> runtime = data.GetRuntime();
389     if (runtime == nullptr) {
390         return E_DB_ERROR;
391     }
392     if (runtime->tokenId != query.tokenId) {
393         ZLOGE("update data failed, query option tokenId not equals data's tokenId");
394         return E_INVALID_PARAMETERS;
395     }
396     runtime->lastModifiedTime = PreProcessUtils::GetTimestamp();
397     unifiedData.SetRuntime(*runtime);
398     for (auto &record : unifiedData.GetRecords()) {
399         record->SetUid(PreProcessUtils::GenerateId());
400     }
401     UdmfConversion::InitValueObject(unifiedData);
402     if (store->Update(unifiedData) != E_OK) {
403         ZLOGE("Update unified data failed, intention: %{public}s.", key.intention.c_str());
404         return E_DB_ERROR;
405     }
406     return E_OK;
407 }
408 
DeleteData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet)409 int32_t UdmfServiceImpl::DeleteData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet)
410 {
411     ZLOGD("start");
412     std::vector<UnifiedData> dataSet;
413     std::shared_ptr<Store> store;
414     auto status = QueryDataCommon(query, dataSet, store);
415     if (status != E_OK) {
416         ZLOGE("QueryDataCommon failed.");
417         return status;
418     }
419     if (dataSet.empty()) {
420         ZLOGW("DataSet has no data, key: %{public}s, intention: %{public}d.", query.key.c_str(), query.intention);
421         return E_OK;
422     }
423     std::shared_ptr<Runtime> runtime;
424     std::vector<std::string> deleteKeys;
425     for (const auto &data : dataSet) {
426         runtime = data.GetRuntime();
427         if (runtime == nullptr) {
428             return E_DB_ERROR;
429         }
430         if (runtime->tokenId == query.tokenId) {
431             unifiedDataSet.push_back(data);
432             deleteKeys.push_back(runtime->key.key);
433         }
434     }
435     if (deleteKeys.empty()) {
436         ZLOGE("Delete nothing. There is no data belonging to this application");
437         return E_OK;
438     }
439     ZLOGI("Delete data start. size: %{public}zu.", deleteKeys.size());
440     if (store->DeleteBatch(deleteKeys) != E_OK) {
441         ZLOGE("Remove data failed.");
442         return E_DB_ERROR;
443     }
444     return E_OK;
445 }
446 
GetSummary(const QueryOption &query, Summary &summary)447 int32_t UdmfServiceImpl::GetSummary(const QueryOption &query, Summary &summary)
448 {
449     ZLOGD("start");
450     UnifiedKey key(query.key);
451     if (!key.IsValid()) {
452         ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str());
453         return E_INVALID_PARAMETERS;
454     }
455 
456     auto store = StoreCache::GetInstance().GetStore(key.intention);
457     if (store == nullptr) {
458         ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str());
459         return E_DB_ERROR;
460     }
461 
462     if (store->GetSummary(query.key, summary) != E_OK) {
463         ZLOGE("Store get summary failed, intention: %{public}s.", key.intention.c_str());
464         return E_DB_ERROR;
465     }
466     return E_OK;
467 }
468 
AddPrivilege(const QueryOption &query, Privilege &privilege)469 int32_t UdmfServiceImpl::AddPrivilege(const QueryOption &query, Privilege &privilege)
470 {
471     ZLOGD("start");
472     UnifiedKey key(query.key);
473     if (!key.IsValid()) {
474         ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str());
475         return E_INVALID_PARAMETERS;
476     }
477 
478     std::string processName;
479     if (!PreProcessUtils::GetNativeProcessNameByToken(query.tokenId, processName)) {
480         return E_ERROR;
481     }
482 
483     if (key.intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) {
484         if (find(DRAG_AUTHORIZED_PROCESSES, std::end(DRAG_AUTHORIZED_PROCESSES), processName) ==
485             std::end(DRAG_AUTHORIZED_PROCESSES)) {
486             ZLOGE("Process: %{public}s has no permission to intention: drag", processName.c_str());
487             return E_NO_PERMISSION;
488         }
489     } else {
490         ZLOGE("Intention: %{public}s has no authorized processes", key.intention.c_str());
491         return E_NO_PERMISSION;
492     }
493 
494     auto store = StoreCache::GetInstance().GetStore(key.intention);
495     if (store == nullptr) {
496         ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str());
497         return E_DB_ERROR;
498     }
499 
500     UnifiedData data;
501     int32_t res = store->Get(query.key, data);
502     if (res == E_NOT_FOUND) {
503         privilegeCache_[query.key] = privilege;
504         ZLOGW("Add privilege in cache, key: %{public}s.", query.key.c_str());
505         return E_OK;
506     }
507     if (res != E_OK) {
508         ZLOGE("Get data from store failed, res:%{public}d,intention: %{public}s.", res, key.intention.c_str());
509         return res;
510     }
511     if (data.GetRuntime() == nullptr) {
512         return E_DB_ERROR;
513     }
514     data.GetRuntime()->privileges.emplace_back(privilege);
515     UdmfConversion::InitValueObject(data);
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         ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str());
531         return E_INVALID_PARAMETERS;
532     }
533 
534     auto store = StoreCache::GetInstance().GetStore(key.intention);
535     if (store == nullptr) {
536         ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str());
537         return E_DB_ERROR;
538     }
539     syncingData_ = true;
540     if (devices.size() > 0) {
541         syncingDevName_ = DistributedData::DeviceManagerAdapter::GetInstance().GetDeviceInfo(devices[0]).deviceName;
542     }
543     auto callback = [this](AsyncProcessInfo &syncInfo) {
544         asyncProcessInfo_.syncId = syncInfo.syncId;
545         asyncProcessInfo_.syncStatus = syncInfo.syncStatus;
546         asyncProcessInfo_.syncTotal = syncInfo.syncTotal;
547         asyncProcessInfo_.syncFinished = syncInfo.syncFinished;
548         asyncProcessInfo_.srcDevName = syncInfo.srcDevName;
549         if (asyncProcessInfo_.syncStatus != ASYNC_RUNNING) {
550             syncingData_ = false;
551         }
552         ZLOGD("store.Sync: name=%{public}s, id=%{public}u, status=%{public}u, total=%{public}u, finish=%{public}u",
553             syncInfo.srcDevName.c_str(), syncInfo.syncId, syncInfo.syncStatus,
554             syncInfo.syncTotal, syncInfo.syncFinished);
555     };
556     if (store->Sync(devices, callback) != E_OK) {
557         syncingData_ = false;
558         ZLOGE("Store sync failed, intention: %{public}s.", key.intention.c_str());
559         RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
560             BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::FAILED, E_DB_ERROR, BizState::DFX_ABNORMAL_END);
561         return E_DB_ERROR;
562     }
563     RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__),
564         BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::SUCCESS, BizState::DFX_NORMAL_END);
565     return E_OK;
566 }
567 
IsRemoteData(const QueryOption &query, bool &result)568 int32_t UdmfServiceImpl::IsRemoteData(const QueryOption &query, bool &result)
569 {
570     UnifiedKey key(query.key);
571     if (!key.IsValid()) {
572         ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str());
573         return E_INVALID_PARAMETERS;
574     }
575 
576     auto store = StoreCache::GetInstance().GetStore(key.intention);
577     if (store == nullptr) {
578         ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str());
579         return E_DB_ERROR;
580     }
581 
582     UnifiedData unifiedData;
583     if (store->Get(query.key, unifiedData) != E_OK) {
584         ZLOGE("Store get unifiedData failed, intention: %{public}s.", key.intention.c_str());
585         return E_DB_ERROR;
586     }
587     std::shared_ptr<Runtime> runtime = unifiedData.GetRuntime();
588     if (runtime == nullptr) {
589         ZLOGE("Store get runtime failed, key: %{public}s.", query.key.c_str());
590         return E_DB_ERROR;
591     }
592 
593     std::string localDeviceId = PreProcessUtils::GetLocalDeviceId();
594     if (localDeviceId != runtime->deviceId) {
595         result = true;
596     }
597     return E_OK;
598 }
599 
SetAppShareOption(const std::string &intention, int32_t shareOption)600 int32_t UdmfServiceImpl::SetAppShareOption(const std::string &intention, int32_t shareOption)
601 {
602     if (intention.empty() || shareOption >= SHARE_OPTIONS_BUTT || shareOption < IN_APP) {
603         ZLOGE("SetAppShareOption : para is invalid, intention: %{public}s, shareOption:%{public}d.",
604               intention.c_str(), shareOption);
605         return E_INVALID_PARAMETERS;
606     }
607 
608     uint64_t accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID();
609     bool isSystemApp = TokenIdKit::IsSystemAppByFullTokenID(accessTokenIDEx);
610     if (!isSystemApp) {
611         ZLOGE("no system permission, intention: %{public}s.", intention.c_str());
612         return E_NO_PERMISSION;
613     }
614     auto store = StoreCache::GetInstance().GetStore(intention);
615     if (store == nullptr) {
616         ZLOGE("Get store failed, intention: %{public}s.", intention.c_str());
617         return E_DB_ERROR;
618     }
619 
620     std::string shareOptionTmp;
621     if (store->GetLocal(std::to_string(accessTokenIDEx), shareOptionTmp) == E_OK) {
622         ZLOGE("SetAppShareOption failed, shareOption has already been set, %{public}s.", shareOptionTmp.c_str());
623         return E_SETTINGS_EXISTED;
624     }
625 
626     if (store->PutLocal(std::to_string(accessTokenIDEx), ShareOptionsUtil::GetEnumStr(shareOption)) != E_OK) {
627         ZLOGE("Store get unifiedData failed, intention: %{public}d.", shareOption);
628         return E_DB_ERROR;
629     }
630     return E_OK;
631 }
632 
GetAppShareOption(const std::string &intention, int32_t &shareOption)633 int32_t UdmfServiceImpl::GetAppShareOption(const std::string &intention, int32_t &shareOption)
634 {
635     if (intention.empty()) {
636         ZLOGE("GetAppShareOption : para is invalid, %{public}s is invalid.", intention.c_str());
637         return E_INVALID_PARAMETERS;
638     }
639     uint64_t accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID();
640     auto store = StoreCache::GetInstance().GetStore(intention);
641     if (store == nullptr) {
642         ZLOGE("Get store failed, intention: %{public}s.", intention.c_str());
643         return E_DB_ERROR;
644     }
645     std::string appShareOption;
646     int32_t ret = store->GetLocal(std::to_string(accessTokenIDEx), appShareOption);
647     if (ret != E_OK) {
648         ZLOGE("GetAppShareOption empty, intention: %{public}s.", intention.c_str());
649         return ret;
650     }
651     ZLOGI("GetAppShareOption, intention: %{public}s, appShareOption:%{public}s.",
652           intention.c_str(), appShareOption.c_str());
653     shareOption = ShareOptionsUtil::GetEnumNum(appShareOption);
654     return E_OK;
655 }
656 
RemoveAppShareOption(const std::string &intention)657 int32_t UdmfServiceImpl::RemoveAppShareOption(const std::string &intention)
658 {
659     if (intention.empty()) {
660         ZLOGE("intention: %{public}s is invalid.", intention.c_str());
661         return E_INVALID_PARAMETERS;
662     }
663     uint64_t accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID();
664     bool isSystemApp = TokenIdKit::IsSystemAppByFullTokenID(accessTokenIDEx);
665     if (!isSystemApp) {
666         ZLOGE("no system permission, intention: %{public}s.", intention.c_str());
667         return E_NO_PERMISSION;
668     }
669     auto store = StoreCache::GetInstance().GetStore(intention);
670     if (store == nullptr) {
671         ZLOGE("Get store failed, intention: %{public}s.", intention.c_str());
672         return E_DB_ERROR;
673     }
674 
675     UnifiedData unifiedData;
676     if (store->DeleteLocal(std::to_string(accessTokenIDEx)) != E_OK) {
677         ZLOGE("Store DeleteLocal failed, intention: %{public}s.", intention.c_str());
678         return E_DB_ERROR;
679     }
680     return E_OK;
681 }
682 
OnInitialize()683 int32_t UdmfServiceImpl::OnInitialize()
684 {
685     ZLOGD("start");
686     Status status = LifeCycleManager::GetInstance().OnStart();
687     if (status != E_OK) {
688         ZLOGE("OnStart execute failed, status: %{public}d", status);
689     }
690     status = LifeCycleManager::GetInstance().StartLifeCycleTimer();
691     if (status != E_OK) {
692         ZLOGE("StartLifeCycleTimer start failed, status: %{public}d", status);
693     }
694     return DistributedData::FeatureSystem::STUB_SUCCESS;
695 }
696 
QueryDataCommon( const QueryOption &query, std::vector<UnifiedData> &dataSet, std::shared_ptr<Store> &store)697 int32_t UdmfServiceImpl::QueryDataCommon(
698     const QueryOption &query, std::vector<UnifiedData> &dataSet, std::shared_ptr<Store> &store)
699 {
700     auto find = UD_INTENTION_MAP.find(query.intention);
701     std::string intention = find == UD_INTENTION_MAP.end() ? intention : find->second;
702     if (!UnifiedDataUtils::IsValidOptions(query.key, intention)) {
703         ZLOGE("Unified key: %{public}s and intention: %{public}s is invalid.", query.key.c_str(), intention.c_str());
704         return E_INVALID_PARAMETERS;
705     }
706     std::string dataPrefix = DATA_PREFIX + intention;
707     UnifiedKey key(query.key);
708     key.IsValid();
709     if (intention.empty()) {
710         dataPrefix = key.key;
711         intention = key.intention;
712     }
713     ZLOGD("dataPrefix = %{public}s, intention: %{public}s.", dataPrefix.c_str(), intention.c_str());
714     store = StoreCache::GetInstance().GetStore(intention);
715     if (store == nullptr) {
716         ZLOGE("Get store failed, intention: %{public}s.", intention.c_str());
717         return E_DB_ERROR;
718     }
719     if (store->GetBatchData(dataPrefix, dataSet) != E_OK) {
720         ZLOGE("Get dataSet failed, dataPrefix: %{public}s.", dataPrefix.c_str());
721         return E_DB_ERROR;
722     }
723     return E_OK;
724 }
725 
OnBind(const BindInfo &bindInfo)726 int32_t UdmfServiceImpl::OnBind(const BindInfo &bindInfo)
727 {
728     executors_ = bindInfo.executors;
729     StoreCache::GetInstance().SetThreadPool(bindInfo.executors);
730     LifeCycleManager::GetInstance().SetThreadPool(bindInfo.executors);
731     UriPermissionManager::GetInstance().SetThreadPool(bindInfo.executors);
732     return 0;
733 }
734 
ObtainAsynProcess(AsyncProcessInfo &processInfo)735 int32_t UdmfServiceImpl::ObtainAsynProcess(AsyncProcessInfo &processInfo)
736 {
737     processInfo = asyncProcessInfo_;
738     if (syncingData_ && processInfo.syncStatus != ASYNC_RUNNING) {
739         processInfo.syncStatus = ASYNC_RUNNING;
740         processInfo.srcDevName = syncingDevName_;
741     }
742     return E_OK;
743 }
744 
ClearAsynProcess()745 int32_t UdmfServiceImpl::ClearAsynProcess()
746 {
747     (void)memset_s(&asyncProcessInfo_, sizeof(asyncProcessInfo_), 0, sizeof(asyncProcessInfo_));
748     return E_OK;
749 }
750 } // namespace UDMF
751 } // namespace OHOS