• 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 #define LOG_TAG "UdmfServiceImpl"
16 
17 #include "udmf_service_impl.h"
18 
19 #include "iservice_registry.h"
20 
21 #include "checker_manager.h"
22 #include "dfx_types.h"
23 #include "distributed_kv_data_manager.h"
24 #include "file.h"
25 #include "lifecycle/lifecycle_manager.h"
26 #include "log_print.h"
27 #include "preprocess_utils.h"
28 #include "reporter.h"
29 #include "uri_permission_manager.h"
30 #include "uri.h"
31 #include "utd/custom_utd_installer.h"
32 
33 namespace OHOS {
34 namespace UDMF {
35 using FeatureSystem = DistributedData::FeatureSystem;
36 using UdmfBehaviourMsg = OHOS::DistributedDataDfx::UdmfBehaviourMsg;
37 using Reporter = OHOS::DistributedDataDfx::Reporter;
38 constexpr const char *DRAG_AUTHORIZED_PROCESSES[] = {"msdp_sa", "collaboration_service"};
39 constexpr const char *DATA_PREFIX = "udmf://";
40 __attribute__((used)) UdmfServiceImpl::Factory UdmfServiceImpl::factory_;
Factory()41 UdmfServiceImpl::Factory::Factory()
42 {
43     ZLOGI("Register udmf creator!");
44     FeatureSystem::GetInstance().RegisterCreator("udmf", [this]() {
45         if (product_ == nullptr) {
46             product_ = std::make_shared<UdmfServiceImpl>();
47         }
48         return product_;
49     }, FeatureSystem::BIND_NOW);
50     staticActs_ = std::make_shared<UdmfStatic>();
51     FeatureSystem::GetInstance().RegisterStaticActs("udmf", staticActs_);
52 }
53 
~Factory()54 UdmfServiceImpl::Factory::~Factory()
55 {
56     product_ = nullptr;
57 }
58 
UdmfServiceImpl()59 UdmfServiceImpl::UdmfServiceImpl()
60 {
61     CheckerManager::GetInstance().LoadCheckers();
62 }
63 
SetData(CustomOption & option,UnifiedData & unifiedData,std::string & key)64 int32_t UdmfServiceImpl::SetData(CustomOption &option, UnifiedData &unifiedData, std::string &key)
65 {
66     ZLOGD("start");
67     int32_t res = E_OK;
68     UdmfBehaviourMsg msg;
69     auto find = UD_INTENTION_MAP.find(option.intention);
70     msg.channel = find == UD_INTENTION_MAP.end() ? "invalid" : find->second;
71     msg.operation = "insert";
72     std::string bundleName;
73     if (!PreProcessUtils::GetHapBundleNameByToken(option.tokenId, bundleName)) {
74         msg.appId = "unknown";
75         res = E_ERROR;
76     } else {
77         msg.appId = bundleName;
78         res = SaveData(option, unifiedData, key);
79     }
80     auto errFind = ERROR_MAP.find(res);
81     msg.result = errFind == ERROR_MAP.end() ? "E_ERROR" : errFind->second;
82     msg.dataType = unifiedData.GetTypes();
83     msg.dataSize = unifiedData.GetSize();
84     Reporter::GetInstance()->BehaviourReporter()->UDMFReport(msg);
85     return res;
86 }
87 
SaveData(CustomOption & option,UnifiedData & unifiedData,std::string & key)88 int32_t UdmfServiceImpl::SaveData(CustomOption &option, UnifiedData &unifiedData, std::string &key)
89 {
90     if (!unifiedData.IsValid()) {
91         ZLOGE("UnifiedData is invalid.");
92         return E_INVALID_PARAMETERS;
93     }
94 
95     if (!UnifiedDataUtils::IsValidIntention(option.intention)) {
96         ZLOGE("Invalid parameters intention: %{public}d.", option.intention);
97         return E_INVALID_PARAMETERS;
98     }
99 
100     // imput runtime info before put it into store and save one privilege
101     if (PreProcessUtils::RuntimeDataImputation(unifiedData, option) != E_OK) {
102         ZLOGE("Imputation failed");
103         return E_ERROR;
104     }
105 
106     std::string intention = unifiedData.GetRuntime()->key.intention;
107     if (intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) {
108         int32_t ret = PreProcessUtils::SetRemoteUri(option.tokenId, unifiedData);
109         if (ret != E_OK) {
110             ZLOGE("SetRemoteUri failed, ret: %{public}d.", ret);
111             return ret;
112         }
113     }
114 
115     for (const auto &record : unifiedData.GetRecords()) {
116         record->SetUid(PreProcessUtils::GenerateId());
117     }
118 
119     auto store = StoreCache::GetInstance().GetStore(intention);
120     if (store == nullptr) {
121         ZLOGE("Get store failed, intention: %{public}s.", intention.c_str());
122         return E_DB_ERROR;
123     }
124 
125     if (!UnifiedDataUtils::IsPersist(intention) && store->Clear() != E_OK) {
126         ZLOGE("Clear store failed, intention: %{public}s.", intention.c_str());
127         return E_DB_ERROR;
128     }
129 
130     if (store->Put(unifiedData) != E_OK) {
131         ZLOGE("Put unified data failed, intention: %{public}s.", intention.c_str());
132         return E_DB_ERROR;
133     }
134     key = unifiedData.GetRuntime()->key.GetUnifiedKey();
135     ZLOGD("Put unified data successful, key: %{public}s.", key.c_str());
136     return E_OK;
137 }
138 
GetData(const QueryOption & query,UnifiedData & unifiedData)139 int32_t UdmfServiceImpl::GetData(const QueryOption &query, UnifiedData &unifiedData)
140 {
141     ZLOGD("start");
142     int32_t res = E_OK;
143     UdmfBehaviourMsg msg;
144     auto find = UD_INTENTION_MAP.find(query.intention);
145     msg.channel = find == UD_INTENTION_MAP.end() ? "invalid" : find->second;
146     msg.operation = "insert";
147     std::string bundleName;
148     if (!PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName)) {
149         msg.appId = "unknown";
150         res = E_ERROR;
151     } else {
152         msg.appId = bundleName;
153         res = RetrieveData(query, unifiedData);
154     }
155     auto errFind = ERROR_MAP.find(res);
156     msg.result = errFind == ERROR_MAP.end() ? "E_ERROR" : errFind->second;
157     msg.dataType = unifiedData.GetTypes();
158     msg.dataSize = unifiedData.GetSize();
159     Reporter::GetInstance()->BehaviourReporter()->UDMFReport(msg);
160     return res;
161 }
162 
RetrieveData(const QueryOption & query,UnifiedData & unifiedData)163 int32_t UdmfServiceImpl::RetrieveData(const QueryOption &query, UnifiedData &unifiedData)
164 {
165     UnifiedKey key(query.key);
166     if (!key.IsValid()) {
167         ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str());
168         return E_INVALID_PARAMETERS;
169     }
170     auto store = StoreCache::GetInstance().GetStore(key.intention);
171     if (store == nullptr) {
172         ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str());
173         return E_DB_ERROR;
174     }
175     int32_t res = store->Get(query.key, unifiedData);
176     if (res != E_OK) {
177         ZLOGE("Get data from store failed, res: %{public}d, key: %{public}s.", res, query.key.c_str());
178         return res;
179     }
180 
181     if (!unifiedData.IsComplete()) {
182         ZLOGE("Get data from DB is incomplete, key: %{public}s.", query.key.c_str());
183         return E_NOT_FOUND;
184     }
185 
186     CheckerManager::CheckInfo info;
187     info.tokenId = query.tokenId;
188     std::shared_ptr<Runtime> runtime = unifiedData.GetRuntime();
189     if (runtime == nullptr) {
190         return E_DB_ERROR;
191     }
192     if (!CheckerManager::GetInstance().IsValid(runtime->privileges, info) && !IsPermissionInCache(query)) {
193         return E_NO_PERMISSION;
194     }
195 
196     if (key.intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) {
197         int32_t ret = ProcessUri(query, unifiedData);
198         if (ret != E_OK) {
199             ZLOGE("DragUriProcessing failed. ret=%{public}d", ret);
200             return E_NO_PERMISSION;
201         }
202     }
203 
204     if (LifeCycleManager::GetInstance().OnGot(key) != E_OK) {
205         ZLOGE("Remove data failed, intention: %{public}s.", key.intention.c_str());
206         return E_DB_ERROR;
207     }
208     privilegeCache_.erase(query.key);
209 
210     PreProcessUtils::SetRemoteData(unifiedData);
211     return E_OK;
212 }
213 
IsPermissionInCache(const QueryOption & query)214 bool UdmfServiceImpl::IsPermissionInCache(const QueryOption &query)
215 {
216     auto iter = privilegeCache_.find(query.key);
217     if (iter != privilegeCache_.end() && iter->second.tokenId == query.tokenId) {
218         return true;
219     }
220     return false;
221 }
222 
ProcessUri(const QueryOption & query,UnifiedData & unifiedData)223 int32_t UdmfServiceImpl::ProcessUri(const QueryOption &query, UnifiedData &unifiedData)
224 {
225     std::string localDeviceId = PreProcessUtils::GetLocalDeviceId();
226     auto records = unifiedData.GetRecords();
227     if (unifiedData.GetRuntime() == nullptr) {
228         return E_DB_ERROR;
229     }
230     std::string sourceDeviceId = unifiedData.GetRuntime()->deviceId;
231     if (localDeviceId != sourceDeviceId) {
232         SetRemoteUri(query, records);
233     }
234 
235     std::string bundleName;
236     if (!PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName)) {
237         ZLOGE("GetHapBundleNameByToken fail, key=%{public}s, tokenId=%{private}d.", query.key.c_str(), query.tokenId);
238         return E_ERROR;
239     }
240     for (auto record : records) {
241         if (record != nullptr && PreProcessUtils::IsFileType(record->GetType())) {
242             auto file = static_cast<File *>(record.get());
243             if (file->GetUri().empty()) {
244                 ZLOGW("Get uri is empty, key=%{public}s.", query.key.c_str());
245                 continue;
246             }
247             Uri uri(file->GetUri());
248             if (uri.GetAuthority().empty()) {
249                 ZLOGW("Get authority is empty, key=%{public}s.", query.key.c_str());
250                 continue;
251             }
252             if (localDeviceId == sourceDeviceId && bundleName == unifiedData.GetRuntime()->sourcePackage) {
253                 ZLOGW("No need to grant uri permissions, bundleName=%{public}s.", bundleName.c_str());
254                 continue;
255             }
256             if (UriPermissionManager::GetInstance().GrantUriPermission(file->GetUri(), bundleName) != E_OK) {
257                 ZLOGE("GrantUriPermission fail, uriAuthority=%{public}s, bundleName=%{public}s, key=%{public}s.",
258                     uri.GetAuthority().c_str(), bundleName.c_str(), query.key.c_str());
259                 return E_NO_PERMISSION;
260             }
261         }
262     }
263     return E_OK;
264 }
265 
SetRemoteUri(const QueryOption & query,std::vector<std::shared_ptr<UnifiedRecord>> & records)266 void UdmfServiceImpl::SetRemoteUri(const QueryOption &query, std::vector<std::shared_ptr<UnifiedRecord>> &records)
267 {
268     for (auto record : records) {
269         if (record != nullptr && PreProcessUtils::IsFileType(record->GetType())) {
270             auto file = static_cast<File *>(record.get());
271             std::string remoteUri = file->GetRemoteUri();
272             if (remoteUri.empty()) {
273                 ZLOGW("Get remoteUri is empyt, key=%{public}s.", query.key.c_str());
274                 continue;
275             }
276             file->SetUri(remoteUri); // cross dev, need dis path.
277         }
278     }
279 }
280 
GetBatchData(const QueryOption & query,std::vector<UnifiedData> & unifiedDataSet)281 int32_t UdmfServiceImpl::GetBatchData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet)
282 {
283     ZLOGD("start");
284     std::vector<UnifiedData> dataSet;
285     std::shared_ptr<Store> store;
286     auto status = QueryDataCommon(query, dataSet, store);
287     if (status != E_OK) {
288         ZLOGE("QueryDataCommon failed.");
289         return status;
290     }
291     if (dataSet.empty()) {
292         ZLOGW("DataSet has no data, key: %{public}s, intention: %{public}d.", query.key.c_str(), query.intention);
293         return E_OK;
294     }
295     for (auto &data : dataSet) {
296         PreProcessUtils::SetRemoteData(data);
297         unifiedDataSet.push_back(data);
298     }
299     return E_OK;
300 }
301 
UpdateData(const QueryOption & query,UnifiedData & unifiedData)302 int32_t UdmfServiceImpl::UpdateData(const QueryOption &query, UnifiedData &unifiedData)
303 {
304     ZLOGD("start");
305     if (!unifiedData.IsValid()) {
306         ZLOGE("UnifiedData is invalid.");
307         return E_INVALID_PARAMETERS;
308     }
309 
310     UnifiedKey key(query.key);
311     if (!key.IsValid()) {
312         ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str());
313         return E_INVALID_PARAMETERS;
314     }
315     auto store = StoreCache::GetInstance().GetStore(key.intention);
316     if (store == nullptr) {
317         ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str());
318         return E_DB_ERROR;
319     }
320 
321     UnifiedData data;
322     int32_t res = store->Get(query.key, data);
323     if (res != E_OK) {
324         ZLOGE("Get data from store failed, intention: %{public}s.", key.intention.c_str());
325         return res;
326     }
327     if (data.IsEmpty()) {
328         ZLOGE("Invalid parameter, unified data has no record; intention: %{public}s.", key.intention.c_str());
329         return E_INVALID_PARAMETERS;
330     }
331     std::shared_ptr<Runtime> runtime = data.GetRuntime();
332     if (runtime == nullptr) {
333         return E_DB_ERROR;
334     }
335     runtime->lastModifiedTime = PreProcessUtils::GetTimestamp();
336     unifiedData.SetRuntime(*runtime);
337     for (auto &record : unifiedData.GetRecords()) {
338         record->SetUid(PreProcessUtils::GenerateId());
339     }
340     if (store->Update(unifiedData) != E_OK) {
341         ZLOGE("Update unified data failed, intention: %{public}s.", key.intention.c_str());
342         return E_DB_ERROR;
343     }
344     return E_OK;
345 }
346 
DeleteData(const QueryOption & query,std::vector<UnifiedData> & unifiedDataSet)347 int32_t UdmfServiceImpl::DeleteData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet)
348 {
349     ZLOGD("start");
350     std::vector<UnifiedData> dataSet;
351     std::shared_ptr<Store> store;
352     auto status = QueryDataCommon(query, dataSet, store);
353     if (status != E_OK) {
354         ZLOGE("QueryDataCommon failed.");
355         return status;
356     }
357     if (dataSet.empty()) {
358         ZLOGW("DataSet has no data, key: %{public}s, intention: %{public}d.", query.key.c_str(), query.intention);
359         return E_OK;
360     }
361     std::shared_ptr<Runtime> runtime;
362     std::vector<std::string> deleteKeys;
363     for (const auto &data : dataSet) {
364         runtime = data.GetRuntime();
365         if (runtime == nullptr) {
366             return E_DB_ERROR;
367         }
368         unifiedDataSet.push_back(data);
369         deleteKeys.push_back(runtime->key.key);
370     }
371     if (store->DeleteBatch(deleteKeys) != E_OK) {
372         ZLOGE("Remove data failed.");
373         return E_DB_ERROR;
374     }
375     return E_OK;
376 }
377 
GetSummary(const QueryOption & query,Summary & summary)378 int32_t UdmfServiceImpl::GetSummary(const QueryOption &query, Summary &summary)
379 {
380     ZLOGD("start");
381     UnifiedKey key(query.key);
382     if (!key.IsValid()) {
383         ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str());
384         return E_INVALID_PARAMETERS;
385     }
386 
387     auto store = StoreCache::GetInstance().GetStore(key.intention);
388     if (store == nullptr) {
389         ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str());
390         return E_DB_ERROR;
391     }
392 
393     if (store->GetSummary(query.key, summary) != E_OK) {
394         ZLOGE("Store get summary failed, intention: %{public}s.", key.intention.c_str());
395         return E_DB_ERROR;
396     }
397     return E_OK;
398 }
399 
AddPrivilege(const QueryOption & query,Privilege & privilege)400 int32_t UdmfServiceImpl::AddPrivilege(const QueryOption &query, Privilege &privilege)
401 {
402     ZLOGD("start");
403     UnifiedKey key(query.key);
404     if (!key.IsValid()) {
405         ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str());
406         return E_INVALID_PARAMETERS;
407     }
408 
409     std::string processName;
410     if (!PreProcessUtils::GetNativeProcessNameByToken(query.tokenId, processName)) {
411         return E_ERROR;
412     }
413 
414     if (key.intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) {
415         if (find(DRAG_AUTHORIZED_PROCESSES, std::end(DRAG_AUTHORIZED_PROCESSES), processName) ==
416             std::end(DRAG_AUTHORIZED_PROCESSES)) {
417             ZLOGE("Process: %{public}s has no permission to intention: drag", processName.c_str());
418             return E_NO_PERMISSION;
419         }
420     } else {
421         ZLOGE("Intention: %{public}s has no authorized processes", key.intention.c_str());
422         return E_NO_PERMISSION;
423     }
424 
425     auto store = StoreCache::GetInstance().GetStore(key.intention);
426     if (store == nullptr) {
427         ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str());
428         return E_DB_ERROR;
429     }
430 
431     UnifiedData data;
432     int32_t res = store->Get(query.key, data);
433     if (res == E_NOT_FOUND) {
434         privilegeCache_[query.key] = privilege;
435         ZLOGW("Add privilege in cache, key: %{public}s.", query.key.c_str());
436         return E_OK;
437     }
438     if (res != E_OK) {
439         ZLOGE("Get data from store failed, res:%{public}d,intention: %{public}s.", res, key.intention.c_str());
440         return res;
441     }
442     if (data.GetRuntime() == nullptr) {
443         return E_DB_ERROR;
444     }
445     data.GetRuntime()->privileges.emplace_back(privilege);
446     if (store->Update(data) != E_OK) {
447         ZLOGE("Update unified data failed, intention: %{public}s.", key.intention.c_str());
448         return E_DB_ERROR;
449     }
450     return E_OK;
451 }
452 
Sync(const QueryOption & query,const std::vector<std::string> & devices)453 int32_t UdmfServiceImpl::Sync(const QueryOption &query, const std::vector<std::string> &devices)
454 {
455     ZLOGD("start");
456     UnifiedKey key(query.key);
457     if (!key.IsValid()) {
458         ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str());
459         return E_INVALID_PARAMETERS;
460     }
461 
462     auto store = StoreCache::GetInstance().GetStore(key.intention);
463     if (store == nullptr) {
464         ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str());
465         return E_DB_ERROR;
466     }
467 
468     if (store->Sync(devices) != E_OK) {
469         ZLOGE("Store sync failed, intention: %{public}s.", key.intention.c_str());
470         return E_DB_ERROR;
471     }
472     return E_OK;
473 }
474 
OnInitialize()475 int32_t UdmfServiceImpl::OnInitialize()
476 {
477     ZLOGD("start");
478     Status status = LifeCycleManager::GetInstance().OnStart();
479     if (status != E_OK) {
480         ZLOGE("OnStart execute failed, status: %{public}d", status);
481     }
482     status = LifeCycleManager::GetInstance().StartLifeCycleTimer();
483     if (status != E_OK) {
484         ZLOGE("StartLifeCycleTimer start failed, status: %{public}d", status);
485     }
486     return DistributedData::FeatureSystem::STUB_SUCCESS;
487 }
488 
QueryDataCommon(const QueryOption & query,std::vector<UnifiedData> & dataSet,std::shared_ptr<Store> & store)489 int32_t UdmfServiceImpl::QueryDataCommon(
490     const QueryOption &query, std::vector<UnifiedData> &dataSet, std::shared_ptr<Store> &store)
491 {
492     auto find = UD_INTENTION_MAP.find(query.intention);
493     std::string intention = find == UD_INTENTION_MAP.end() ? intention : find->second;
494     if (!UnifiedDataUtils::IsValidOptions(query.key, intention)) {
495         ZLOGE("Unified key: %{public}s and intention: %{public}s is invalid.", query.key.c_str(), intention.c_str());
496         return E_INVALID_PARAMETERS;
497     }
498     std::string dataPrefix = DATA_PREFIX + intention;
499     UnifiedKey key(query.key);
500     key.IsValid();
501     if (intention.empty()) {
502         dataPrefix = key.key;
503         intention = key.intention;
504     }
505     ZLOGD("dataPrefix = %{public}s, intention: %{public}s.", dataPrefix.c_str(), intention.c_str());
506     store = StoreCache::GetInstance().GetStore(intention);
507     if (store == nullptr) {
508         ZLOGE("Get store failed, intention: %{public}s.", intention.c_str());
509         return E_DB_ERROR;
510     }
511     if (store->GetBatchData(dataPrefix, dataSet) != E_OK) {
512         ZLOGE("Get dataSet failed, dataPrefix: %{public}s.", dataPrefix.c_str());
513         return E_DB_ERROR;
514     }
515     return E_OK;
516 }
517 
OnBind(const BindInfo & bindInfo)518 int32_t UdmfServiceImpl::OnBind(const BindInfo &bindInfo)
519 {
520     executors_ = bindInfo.executors;
521     StoreCache::GetInstance().SetThreadPool(bindInfo.executors);
522     LifeCycleManager::GetInstance().SetThreadPool(bindInfo.executors);
523     return 0;
524 }
525 
OnAppInstall(const std::string & bundleName,int32_t user,int32_t index)526 int32_t UdmfServiceImpl::UdmfStatic::OnAppInstall(const std::string &bundleName, int32_t user,
527     int32_t index)
528 {
529     ZLOGD("Bundle: %{public}s installed.", bundleName.c_str());
530     auto status = CustomUtdInstaller::GetInstance().InstallUtd(bundleName, user);
531     if (status != E_OK) {
532         ZLOGE("Install Utd failed, bundleName: %{public}s, status: %{public}d", bundleName.c_str(), status);
533     }
534     return status;
535 }
536 
OnAppUpdate(const std::string & bundleName,int32_t user,int32_t index)537 int32_t UdmfServiceImpl::UdmfStatic::OnAppUpdate(const std::string &bundleName, int32_t user,
538     int32_t index)
539 {
540     ZLOGD("Bundle: %{public}s Update.", bundleName.c_str());
541     auto status = CustomUtdInstaller::GetInstance().UninstallUtd(bundleName, user);
542     if (status != E_OK) {
543         ZLOGE("Uninstall utd failed, bundleName: %{public}s, status: %{public}d.", bundleName.c_str(), status);
544         return status;
545     }
546     status = CustomUtdInstaller::GetInstance().InstallUtd(bundleName, user);
547     if (status != E_OK) {
548         ZLOGE("Install utd failed, bundleName: %{public}s, status: %{public}d.", bundleName.c_str(), status);
549     }
550     return status;
551 }
552 
OnAppUninstall(const std::string & bundleName,int32_t user,int32_t index)553 int32_t UdmfServiceImpl::UdmfStatic::OnAppUninstall(const std::string &bundleName, int32_t user,
554     int32_t index)
555 {
556     ZLOGD("Bundle: %{public}s uninstalled.", bundleName.c_str());
557     auto status = CustomUtdInstaller::GetInstance().UninstallUtd(bundleName, user);
558     if (status != E_OK) {
559         ZLOGE("Uninstall utd failed, bundleName: %{public}s, status: %{public}d.", bundleName.c_str(), status);
560     }
561     return status;
562 }
563 } // namespace UDMF
564 } // namespace OHOS