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