1/*
2* Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development 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#include "app_data_parser.h"
16
17#include "accesstoken_kit.h"
18#include "common_event_manager.h"
19#include "iservice_registry.h"
20#include "loghelper.h"
21#include "nfc_sdk_common.h"
22#include "system_ability_definition.h"
23#include "taginfo.h"
24#include "nfc_permission_checker.h"
25
26namespace OHOS {
27namespace NFC {
28const int USER_ID = 100;
29static AppDataParser g_appDataParser;
30/** Tag type of tag app metadata name */
31static const std::string KEY_TAG_TECH = "tag-tech";
32std::mutex g_appListInitMutex = {};
33sptr<BundleMgrDeathRecipient> bundleMgrDeathRecipient_(new (std::nothrow) BundleMgrDeathRecipient());
34
35void BundleMgrDeathRecipient::OnRemoteDied([[maybe_unused]] const wptr<IRemoteObject> &remote)
36{
37    InfoLog("bundleMgrService dead");
38};
39
40AppDataParser::AppDataParser()
41{
42    g_tagAppAndTechMap.clear();
43    g_hceAppAndAidMap.clear();
44}
45
46AppDataParser::~AppDataParser()
47{
48}
49
50AppDataParser& AppDataParser::GetInstance()
51{
52    return g_appDataParser;
53}
54
55sptr<AppExecFwk::IBundleMgr> AppDataParser::GetBundleMgrProxy()
56{
57    sptr<ISystemAbilityManager> systemAbilityManager =
58        SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
59    if (!systemAbilityManager) {
60        ErrorLog("GetBundleMgrProxy, systemAbilityManager is null");
61        return nullptr;
62    }
63    sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
64    if (!remoteObject) {
65        ErrorLog("GetBundleMgrProxy, remoteObject is null");
66        return nullptr;
67    }
68    sptr<AppExecFwk::IBundleMgr> bundleMgrProxy = iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
69    bundleMgrProxy->AsObject()->AddDeathRecipient(bundleMgrDeathRecipient_);
70    return bundleMgrProxy;
71}
72
73bool AppDataParser::HandleAppAddOrChangedEvent(std::shared_ptr<EventFwk::CommonEventData> data)
74{
75    if (data == nullptr) {
76        ErrorLog("HandleAppAddOrChangedEvent, invalid data.");
77        return false;
78    }
79    ElementName element = data->GetWant().GetElement();
80    std::string bundleName = element.GetBundleName();
81    if (bundleName.empty()) {
82        ErrorLog("HandleAppAddOrChangedEvent, invaid bundleName.");
83        return false;
84    }
85    DebugLog("HandleAppAddOrChangedEvent bundlename: %{public}s", bundleName.c_str());
86    bool tag = UpdateAppListInfo(element, KITS::ACTION_TAG_FOUND);
87    bool host = UpdateAppListInfo(element, KITS::ACTION_HOST_APDU_SERVICE);
88    bool offHost = UpdateAppListInfo(element, KITS::ACTION_OFF_HOST_APDU_SERVICE);
89    return tag || host || offHost;
90}
91
92bool AppDataParser::HandleAppRemovedEvent(std::shared_ptr<EventFwk::CommonEventData> data)
93{
94    if (data == nullptr) {
95        ErrorLog("HandleAppRemovedEvent, invalid data.");
96        return false;
97    }
98    ElementName element = data->GetWant().GetElement();
99    std::string bundleName = element.GetBundleName();
100    if (bundleName.empty()) {
101        ErrorLog("HandleAppRemovedEvent, invalid bundleName.");
102        return false;
103    }
104    DebugLog("HandleAppRemovedEvent, bundleName %{public}s tag size %{public}zu, hce size %{public}zu",
105        bundleName.c_str(),
106        g_tagAppAndTechMap.size(),
107        g_hceAppAndAidMap.size());
108    bool tag = RemoveTagAppInfo(element);
109    bool hce = RemoveHceAppInfo(element);
110    bool offHost = RemoveOffHostAppInfo(element);
111    return tag || hce || offHost;
112}
113
114bool AppDataParser::VerifyHapPermission(const std::string bundleName, const std::string action)
115{
116    std::string permissionNfc;
117    OHOS::Security::AccessToken::AccessTokenID tokenID;
118    std::map<std::string, std::string> permissionMap = {
119        {KITS::ACTION_TAG_FOUND, TAG_PERM},
120        {KITS::ACTION_HOST_APDU_SERVICE, CARD_EMU_PERM},
121        {KITS::ACTION_OFF_HOST_APDU_SERVICE, CARD_EMU_PERM}
122    };
123    std::map<std::string, std::string>::iterator it = permissionMap.find(action.c_str());
124    if (it != permissionMap.end()) {
125        permissionNfc = it->second;
126    } else {
127        ErrorLog("VerifyHapPermission, action no in map!");
128        return false;
129    }
130    tokenID= OHOS::Security::AccessToken::AccessTokenKit::GetHapTokenID(USER_ID, bundleName, 0);
131    int result = OHOS::Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenID, permissionNfc);
132    if (result != OHOS::Security::AccessToken::PERMISSION_GRANTED) {
133        ErrorLog("bundleName %{public}s no permission %{public}s", bundleName.c_str(), permissionNfc.c_str());
134        return false;
135    }
136    return true;
137}
138
139void AppDataParser::QueryAbilityInfos(const std::string action, std::vector<AbilityInfo> &abilityInfos,
140    std::vector<ExtensionAbilityInfo> &extensionInfos)
141{
142    sptr<AppExecFwk::IBundleMgr> bundleMgrProxy = GetBundleMgrProxy();
143    if (bundleMgrProxy == nullptr) {
144        ErrorLog("QueryAbilityInfos, bundleMgrProxy is nullptr.");
145        return;
146    }
147    AAFwk::Want want;
148    want.SetAction(action);
149    if (KITS::ACTION_TAG_FOUND == action) {
150        // only tag action have uris
151        want.SetType("*/*");
152    }
153
154    bool withDefault = false;
155    bool findDefaultApp = false;
156    auto abilityInfoFlag = AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_DEFAULT
157        | AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_SKILL_URI
158        | AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA;
159    if (!bundleMgrProxy->ImplicitQueryInfos(want, abilityInfoFlag, USER_ID, withDefault,
160        abilityInfos, extensionInfos, findDefaultApp)) {
161        WarnLog("QueryAbilityInfos, query none for action %{public}s", action.c_str());
162        return;
163    }
164}
165
166bool AppDataParser::UpdateAppListInfo(ElementName &element, const std::string action)
167{
168    if (action.compare(KITS::ACTION_TAG_FOUND) != 0 && action.compare(KITS::ACTION_HOST_APDU_SERVICE) != 0 &&
169        action != KITS::ACTION_OFF_HOST_APDU_SERVICE) {
170        DebugLog("UpdateAppListInfo, ignore action = %{public}s", action.c_str());
171        return false;
172    }
173    std::string bundleName = element.GetBundleName();
174    if (!VerifyHapPermission(bundleName, action)) {
175        DebugLog("Hap have no permission for action = %{public}s", action.c_str());
176        return false;
177    }
178
179    // query the applications infos that're matched with the acitons.
180    std::vector<AbilityInfo> abilityInfos;
181    std::vector<ExtensionAbilityInfo> extensionAbilityInfos;
182    QueryAbilityInfos(action, abilityInfos, extensionAbilityInfos);
183    for (auto& abilityInfo : abilityInfos) {
184        if (bundleName.empty() || bundleName.compare(abilityInfo.bundleName) != 0) {
185            continue;
186        }
187        ElementName hapElement(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name,
188                abilityInfo.moduleName);
189        if (action.compare(KITS::ACTION_TAG_FOUND) == 0) {
190            UpdateTagAppList(abilityInfo, hapElement);
191        }
192        if (action.compare(KITS::ACTION_HOST_APDU_SERVICE) == 0) {
193            UpdateHceAppList(abilityInfo, hapElement);
194        }
195        if (action.compare(KITS::ACTION_OFF_HOST_APDU_SERVICE) == 0) {
196            UpdateOffHostAppList(abilityInfo, hapElement);
197        }
198    }
199    return true;
200}
201
202bool AppDataParser::InitAppListByAction(const std::string action)
203{
204    // query the applications infos that're matched with the acitons.
205    std::vector<AbilityInfo> abilityInfos;
206    std::vector<ExtensionAbilityInfo> extensionAbilityInfos;
207    QueryAbilityInfos(action, abilityInfos, extensionAbilityInfos);
208    if (KITS::ACTION_TAG_FOUND.compare(action) == 0) {
209        for (auto& tagAbilityInfo : abilityInfos) {
210            ElementName element(tagAbilityInfo.deviceId, tagAbilityInfo.bundleName, tagAbilityInfo.name,
211                tagAbilityInfo.moduleName);
212            UpdateTagAppList(tagAbilityInfo, element);
213        }
214    } else if (KITS::ACTION_HOST_APDU_SERVICE.compare(action) == 0) {
215        for (auto& hceAbilityInfo : abilityInfos) {
216            ElementName element(hceAbilityInfo.deviceId, hceAbilityInfo.bundleName, hceAbilityInfo.name,
217                hceAbilityInfo.moduleName);
218            UpdateHceAppList(hceAbilityInfo, element);
219        }
220    } else if (KITS::ACTION_OFF_HOST_APDU_SERVICE.compare(action) == 0) {
221        for (auto& offHostAbilityInfo : abilityInfos) {
222            ElementName element(offHostAbilityInfo.deviceId, offHostAbilityInfo.bundleName, offHostAbilityInfo.name,
223                offHostAbilityInfo.moduleName);
224            UpdateOffHostAppList(offHostAbilityInfo, element);
225        }
226    } else {
227        WarnLog("InitAppListByAction,unknown action = %{public}s", action.c_str());
228    }
229    return true;
230}
231
232bool AppDataParser::IsMatchedByBundleName(ElementName &src, ElementName &target)
233{
234    if (src.GetBundleName().compare(target.GetBundleName()) == 0) {
235        return true;
236    }
237    return false;
238}
239
240ElementName AppDataParser::GetMatchedTagKeyElement(ElementName &element)
241{
242    ElementName emptyElement;
243    std::vector<TagAppTechInfo>::iterator iter;
244    for (iter = g_tagAppAndTechMap.begin(); iter != g_tagAppAndTechMap.end(); ++iter) {
245        if (IsMatchedByBundleName(element, (*iter).element)) {
246            return (*iter).element;
247        }
248    }
249    return emptyElement;
250}
251
252ElementName AppDataParser::GetMatchedHceKeyElement(ElementName &element)
253{
254    ElementName emptyElement;
255    std::vector<HceAppAidInfo>::iterator iter;
256    for (iter = g_hceAppAndAidMap.begin(); iter != g_hceAppAndAidMap.end(); ++iter) {
257        if (IsMatchedByBundleName(element, (*iter).element)) {
258            return (*iter).element;
259        }
260    }
261    return emptyElement;
262}
263
264void AppDataParser::UpdateTagAppList(AbilityInfo &abilityInfo, ElementName &element)
265{
266    if (!GetMatchedTagKeyElement(element).GetBundleName().empty()) {
267        WarnLog("UpdateTagAppList, rm duplicated app %{public}s", element.GetBundleName().c_str());
268        RemoveTagAppInfo(element);
269    }
270    std::vector<std::string> valueList;
271    for (auto& data : abilityInfo.metadata) {
272        if (KEY_TAG_TECH.compare(data.name) == 0) {
273            valueList.emplace_back(data.value);
274            DebugLog("UpdateTagAppList from metadata, push tech %{public}s", data.value.c_str());
275        }
276    }
277    for (auto& data : abilityInfo.metaData.customizeData) {
278        if (KEY_TAG_TECH.compare(data.name) == 0) {
279            valueList.emplace_back(data.value);
280            DebugLog("UpdateTagAppList from customizeData, push tech %{public}s", data.value.c_str());
281        }
282    }
283    for (auto& uri : abilityInfo.skillUri) {
284        if (uri.type.empty()) {
285            continue;
286        }
287        // format example: "type": "tag-tech/NfcA"
288        auto pos = uri.type.find("/");
289        if (pos == std::string::npos) {
290            ErrorLog("UpdateTagAppList from skillUri, separator not found %{public}s", uri.type.c_str());
291            continue;
292        }
293        std::string tech = uri.type.substr(0, pos);
294        if (KEY_TAG_TECH.compare(tech) != 0) {
295            ErrorLog("UpdateTagAppList KEY_TAG_TECH for %{public}s", tech.c_str());
296            continue;
297        }
298        std::string nfcType = uri.type.substr(pos + 1, uri.type.size());
299        if (std::find(valueList.begin(), valueList.end(), nfcType) == valueList.end()) {
300            valueList.emplace_back(nfcType);
301            DebugLog("UpdateTagAppList from skillUri, push tech %{public}s", nfcType.c_str());
302        }
303    }
304
305    if (valueList.empty()) {
306        DebugLog("UpdateTagAppList, ignore for app %{public}s %{public}s", element.GetBundleName().c_str(),
307            element.GetAbilityName().c_str());
308        return;
309    }
310
311    TagAppTechInfo tagAppTechInfo;
312    tagAppTechInfo.element = element;
313    tagAppTechInfo.tech = valueList;
314    g_tagAppAndTechMap.push_back(tagAppTechInfo);
315    DebugLog("UpdateTagAppList, push for app %{public}s %{public}s", element.GetBundleName().c_str(),
316        element.GetAbilityName().c_str());
317}
318
319void AppDataParser::UpdateHceAppList(AbilityInfo &abilityInfo, ElementName &element)
320{
321    if (!GetMatchedHceKeyElement(element).GetBundleName().empty()) {
322        WarnLog("UpdateHceAppList, rm duplicated app %{public}s", element.GetBundleName().c_str());
323        RemoveHceAppInfo(element);
324    }
325    std::vector<AidInfo> customDataAidList;
326    AidInfo customDataAid;
327    for (auto& data : abilityInfo.metadata) {
328        if ((KITS::KEY_PAYMENT_AID.compare(data.name) == 0) || (KITS::KEY_OHTER_AID.compare(data.name) == 0)) {
329            customDataAid.name = data.name;
330            customDataAid.value = data.value;
331            customDataAidList.emplace_back(customDataAid);
332            DebugLog("UpdateHceAppList from metadata, push aid %{public}s", data.value.c_str());
333        }
334    }
335    for (auto& data : abilityInfo.metaData.customizeData) {
336        if ((KITS::KEY_PAYMENT_AID.compare(data.name) == 0) || (KITS::KEY_OHTER_AID.compare(data.name) == 0)) {
337            customDataAid.name = data.name;
338            customDataAid.value = data.value;
339            customDataAidList.emplace_back(customDataAid);
340            DebugLog("UpdateHceAppList from customizeData, push aid %{public}s", data.value.c_str());
341        }
342    }
343    if (customDataAidList.empty()) {
344        DebugLog("UpdateHceAppList, ignore for app %{public}s %{public}s", element.GetBundleName().c_str(),
345            element.GetAbilityName().c_str());
346        return;
347    }
348    HceAppAidInfo hceAppAidInfo;
349    hceAppAidInfo.element = element;
350    hceAppAidInfo.iconId = abilityInfo.iconId;
351    hceAppAidInfo.labelId = abilityInfo.labelId;
352    hceAppAidInfo.customDataAid = customDataAidList;
353    g_hceAppAndAidMap.push_back(hceAppAidInfo);
354    DebugLog("UpdateHceAppList, push for app %{public}s %{public}s", element.GetBundleName().c_str(),
355        element.GetAbilityName().c_str());
356}
357
358void AppDataParser::UpdateOffHostAppList(AbilityInfo &abilityInfo, ElementName &element)
359{
360    if (HaveMatchedOffHostKeyElement(element)) {
361        WarnLog("UpdateOffHostAppList, rm duplicated app %{public}s", element.GetBundleName().c_str());
362        RemoveOffHostAppInfo(element);
363    }
364    HceAppAidInfo offHostAppAidInfo;
365    offHostAppAidInfo.element = element;
366    offHostAppAidInfo.iconId = abilityInfo.iconId;
367    offHostAppAidInfo.labelId = abilityInfo.labelId;
368    g_offHostAppAndAidMap.push_back(offHostAppAidInfo);
369    DebugLog("UpdateOffHostAppList, push for app %{public}s %{public}s", element.GetBundleName().c_str(),
370        element.GetAbilityName().c_str());
371}
372
373bool AppDataParser::HaveMatchedOffHostKeyElement(ElementName &element)
374{
375    std::vector<HceAppAidInfo>::iterator iter;
376    for (iter = g_offHostAppAndAidMap.begin(); iter != g_offHostAppAndAidMap.end(); ++iter) {
377        if (IsMatchedByBundleName(element, (*iter).element)) {
378            return true;
379        }
380    }
381    return false;
382}
383
384bool AppDataParser::RemoveTagAppInfo(ElementName &element)
385{
386    ElementName keyElement = GetMatchedTagKeyElement(element);
387    if (keyElement.GetBundleName().empty()) {
388        WarnLog("RemoveTagAppInfo, keyElement is none, ignore it.");
389        return false;
390    }
391    DebugLog("RemoveTagAppInfo, request app %{public}s", keyElement.GetBundleName().c_str());
392    std::vector<TagAppTechInfo>::iterator iter;
393    for (iter = g_tagAppAndTechMap.begin(); iter != g_tagAppAndTechMap.end(); ++iter) {
394        // compare only bundle name to remote the app.
395        if (IsMatchedByBundleName(element, (*iter).element)) {
396            DebugLog("RemoveTagAppInfo, erase app %{public}s", keyElement.GetBundleName().c_str());
397            g_tagAppAndTechMap.erase(iter);
398            return true;
399        }
400    }
401    return false;
402}
403
404bool AppDataParser::RemoveHceAppInfo(ElementName &element)
405{
406    ElementName keyElement = GetMatchedHceKeyElement(element);
407    if (keyElement.GetBundleName().empty()) {
408        WarnLog("RemoveHceAppInfo, keyElement is none, ignore it.");
409        return false;
410    }
411    DebugLog("RemoveHceAppInfo, app %{public}s", keyElement.GetBundleName().c_str());
412    std::vector<HceAppAidInfo>::iterator iter;
413    for (iter = g_hceAppAndAidMap.begin(); iter != g_hceAppAndAidMap.end(); ++iter) {
414        // compare only bundle name to remote the app.
415        if (IsMatchedByBundleName(element, (*iter).element)) {
416            DebugLog("RemoveHceAppInfo, erase app %{public}s", keyElement.GetBundleName().c_str());
417            g_hceAppAndAidMap.erase(iter);
418            return true;
419        }
420    }
421    return false;
422}
423
424bool AppDataParser::RemoveOffHostAppInfo(ElementName &element)
425{
426    if (!HaveMatchedOffHostKeyElement(element)) {
427        WarnLog("RemoveOffHostAppInfo, keyElement is none, ignore it.");
428        return false;
429    }
430
431    DebugLog("RemoveOffHostAppInfo, app %{public}s", element.GetBundleName().c_str());
432    std::vector<HceAppAidInfo>::iterator iter;
433    for (iter = g_offHostAppAndAidMap.begin(); iter != g_offHostAppAndAidMap.end(); ++iter) {
434        // compare only bundle name to remote the app.
435        if (IsMatchedByBundleName(element, (*iter).element)) {
436            DebugLog("RemoveOffHostAppInfo, erase app %{public}s", element.GetBundleName().c_str());
437            g_offHostAppAndAidMap.erase(iter);
438            return true;
439        }
440    }
441    return false;
442}
443
444void AppDataParser::InitAppList()
445{
446    std::lock_guard<std::mutex> lock(g_appListInitMutex);
447    if (appListInitDone_) {
448        WarnLog("InitAppList: already done");
449        return;
450    }
451    sptr<AppExecFwk::IBundleMgr> bundleMgrProxy = GetBundleMgrProxy();
452    if (!bundleMgrProxy) {
453        ErrorLog("InitAppList, bundleMgrProxy is nullptr.");
454        appListInitDone_ = false;
455        return;
456    }
457    InfoLog("InitAppListByAction start");
458    InitAppListByAction(KITS::ACTION_TAG_FOUND);
459    InitAppListByAction(KITS::ACTION_HOST_APDU_SERVICE);
460    InitAppListByAction(KITS::ACTION_OFF_HOST_APDU_SERVICE);
461    InfoLog("InitAppList, tag size %{public}zu, hce size %{public}zu, off host app  %{public}zu",
462            g_tagAppAndTechMap.size(), g_hceAppAndAidMap.size(), g_offHostAppAndAidMap.size());
463    appListInitDone_ = true;
464}
465
466std::vector<ElementName> AppDataParser::GetDispatchTagAppsByTech(std::vector<int> discTechList)
467{
468    std::vector<ElementName> elements;
469    for (size_t i = 0; i < discTechList.size(); i++) {
470        std::string discStrTech = KITS::TagInfo::GetStringTech(discTechList[i]);
471        DebugLog("GetDispatchTagAppsByTech, tag size = %{public}zu", g_tagAppAndTechMap.size());
472        if (discStrTech.empty()) {
473            continue;
474        }
475
476        // parse for all installed app that can handle this technology.
477        std::vector<TagAppTechInfo>::iterator iter;
478        for (iter = g_tagAppAndTechMap.begin(); iter != g_tagAppAndTechMap.end(); ++iter) {
479            bool appExisted = false;
480            for (auto item : elements) {
481                if (IsMatchedByBundleName(item, (*iter).element)) {
482                    appExisted = true;
483                    break;
484                }
485            }
486            if (appExisted) {
487                continue;
488            }
489
490            std::vector<std::string> vectorTech = (*iter).tech;
491            for (size_t i = 0; i < vectorTech.size(); i++) {
492                DebugLog("GetDispatchTagAppsByTech, cmp tech %{public}s vs %{public}s",
493                    discStrTech.c_str(), vectorTech[i].c_str());
494                if (discStrTech.compare(vectorTech[i]) == 0) {
495                    elements.push_back((*iter).element);
496                    break;
497                }
498            }
499        }
500    }
501    return elements;
502}
503
504#ifdef VENDOR_APPLICATIONS_ENABLED
505std::vector<ElementName> AppDataParser::GetVendorDispatchTagAppsByTech(std::vector<int>& discTechList)
506{
507    std::vector<ElementName> elements {};
508    std::vector<AAFwk::Want> hceAppList {};
509    if (queryApplicationByVendor_ == nullptr) {
510        ErrorLog("AppDataParser::GetVendorDispatchTagAppsByTech queryApplicationByVendor_ is nullptr.");
511        return std::vector<ElementName>();
512    }
513    queryApplicationByVendor_->OnQueryAppInfo(KEY_TAG_APP, discTechList, hceAppList, elements);
514    return elements;
515}
516
517void AppDataParser::RegQueryApplicationCb(sptr<IQueryAppInfoCallback> callback)
518{
519    queryApplicationByVendor_ = callback;
520}
521
522void AppDataParser::RegCardEmulationNotifyCb(sptr<IOnCardEmulationNotifyCb> callback)
523{
524    onCardEmulationNotify_ = callback;
525}
526
527sptr<IOnCardEmulationNotifyCb> AppDataParser::GetNotifyCardEmulationCallback() const
528{
529    return onCardEmulationNotify_;
530}
531#endif
532
533void AppDataParser::GetHceAppsByAid(const std::string& aid, std::vector<AppDataParser::HceAppAidInfo>& hceApps)
534{
535    for (const HceAppAidInfo& appAidInfo : g_hceAppAndAidMap) {
536        for (const AidInfo& aidInfo : appAidInfo.customDataAid) {
537            if (aid == aidInfo.value) {
538                hceApps.push_back(appAidInfo);
539                break;
540            }
541        }
542    }
543}
544
545#ifdef VENDOR_APPLICATIONS_ENABLED
546void AppDataParser::GetHceAppsFromVendor(std::vector<HceAppAidInfo> &hceApps)
547{
548    if (queryApplicationByVendor_ == nullptr) {
549        WarnLog("AppDataParser::GetHceApps queryApplicationByVendor_ is nullptr.");
550        return;
551    }
552    std::vector<int> techList {};
553    std::vector<AAFwk::Want> vendorHceAppAndAidList {};
554    std::vector<AppExecFwk::ElementName> elementNameList {};
555    queryApplicationByVendor_->OnQueryAppInfo(KEY_HCE_APP, techList, vendorHceAppAndAidList, elementNameList);
556    if (vendorHceAppAndAidList.size() != 0) {
557        for (auto appAidInfoWant : vendorHceAppAndAidList) {
558            std::shared_ptr<HceAppAidInfo> appAidInfo = std::make_shared<HceAppAidInfo>();
559            appAidInfo->element = appAidInfoWant.GetElement();
560            const std::string KEY_OTHER_AID = "other-aid";
561            const std::string KEY_PAYMENT_AID = "payment-aid";
562            std::vector<std::string> otherAidList = appAidInfoWant.GetStringArrayParam(KEY_OTHER_AID);
563            std::vector<std::string> paymentAidList = appAidInfoWant.GetStringArrayParam(KEY_PAYMENT_AID);
564            for (std::string otherAid : otherAidList) {
565                std::shared_ptr<AidInfo> aidInfo = std::make_shared<AidInfo>();
566                aidInfo->name = KEY_OTHER_AID;
567                aidInfo->value = otherAid;
568                appAidInfo->customDataAid.push_back(*aidInfo);
569            }
570            for (std::string paymentAid : paymentAidList) {
571                std::shared_ptr<AidInfo> aidInfo = std::make_shared<AidInfo>();
572                aidInfo->name = KEY_PAYMENT_AID;
573                aidInfo->value = paymentAid;
574                appAidInfo->customDataAid.push_back(*aidInfo);
575            }
576            hceApps.push_back(*appAidInfo);
577        }
578    }
579}
580
581void AppDataParser::GetPaymentAbilityInfosFromVendor(std::vector<AbilityInfo> &paymentAbilityInfos)
582{
583    std::vector<HceAppAidInfo> hceApps;
584    std::set<std::string> bundleNames;
585    GetHceAppsFromVendor(hceApps);
586    DebugLog("The hceApps len %{public}lu", hceApps.size());
587    sptr<AppExecFwk::IBundleMgr> bundleMgrProxy = GetBundleMgrProxy();
588    if (bundleMgrProxy == nullptr) {
589        ErrorLog("bundleMgrProxy is nullptr!");
590        return;
591    }
592    for (auto& appAidInfo : hceApps) {
593        DebugLog("The bundlename : %{public}s", appAidInfo.element.GetBundleName().c_str());
594        if (appAidInfo.element.GetBundleName().empty() || !IsPaymentApp(appAidInfo)) {
595            continue;
596        }
597        if (bundleNames.count(appAidInfo.element.GetBundleName()) > 0) {
598            DebugLog("The bundlename : %{public}s is in the bundleNames", appAidInfo.element.GetBundleName().c_str());
599            continue;
600        }
601        bundleNames.insert(appAidInfo.element.GetBundleName());
602        AbilityInfo ability;
603        ability.name = appAidInfo.element.GetAbilityName();
604        ability.bundleName = appAidInfo.element.GetBundleName();
605        AppExecFwk::BundleInfo bundleInfo{};
606        int32_t bundleInfoFlag = static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
607                                 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE) |
608                                 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION);
609        if (bundleMgrProxy == nullptr) {
610            ErrorLog("bundleMgrProxy is nullptr!");
611            break;
612        }
613        bundleMgrProxy->GetBundleInfoV9(
614            ability.bundleName, bundleInfoFlag, bundleInfo, AppExecFwk::Constants::START_USERID);
615        DebugLog("The bundlename : %{public}s,the labelId : %{public}d,the iconId : %{public}d",
616            appAidInfo.element.GetBundleName().c_str(),
617            bundleInfo.applicationInfo.labelId,
618            bundleInfo.applicationInfo.iconId);
619        if (bundleInfo.applicationInfo.labelId != 0 && bundleInfo.applicationInfo.iconId != 0) {
620            ability.labelId = bundleInfo.applicationInfo.labelId;
621            ability.iconId = bundleInfo.applicationInfo.iconId;
622            paymentAbilityInfos.push_back(ability);
623        }
624    }
625}
626
627bool AppDataParser::IsHceAppFromVendor(const ElementName &elementName)
628{
629    std::vector<HceAppAidInfo> hceApps;
630    GetHceAppsFromVendor(hceApps);
631    for (auto &app : hceApps) {
632        if (app.element.GetBundleName() == elementName.GetBundleName() &&
633            app.element.GetAbilityName() == elementName.GetAbilityName()) {
634            return true;
635        }
636    }
637    return false;
638}
639#endif
640bool AppDataParser::IsBundleInstalled(const std::string &bundleName)
641{
642    sptr<AppExecFwk::IBundleMgr> bundleMgrProxy = GetBundleMgrProxy();
643    if (bundleMgrProxy == nullptr) {
644        ErrorLog("bundleMgrProxy is nullptr!");
645        return false;
646    }
647    if (bundleName.empty()) {
648        ErrorLog("bundle name is empty");
649        return false;
650    }
651    AppExecFwk::BundleInfo bundleInfo;
652    bool result = bundleMgrProxy->GetBundleInfo(bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT,
653                                                bundleInfo, USER_ID);
654    ErrorLog("get bundle %{public}s result %{public}d ", bundleName.c_str(), result);
655    return result;
656}
657void AppDataParser::GetHceApps(std::vector<HceAppAidInfo> &hceApps)
658{
659    for (const HceAppAidInfo &appAidInfo : g_hceAppAndAidMap) {
660        hceApps.push_back(appAidInfo);
661    }
662#ifdef VENDOR_APPLICATIONS_ENABLED
663    GetHceAppsFromVendor(hceApps);
664#endif
665}
666
667bool AppDataParser::IsPaymentApp(const AppDataParser::HceAppAidInfo &hceAppInfo)
668{
669    for (const AppDataParser::AidInfo &aidInfo : hceAppInfo.customDataAid) {
670        if (KITS::KEY_PAYMENT_AID == aidInfo.name) {
671            return true;
672        }
673    }
674    return false;
675}
676
677bool AppDataParser::IsHceApp(const ElementName &elementName)
678{
679    for (const AppDataParser::HceAppAidInfo &appAidInfo : g_hceAppAndAidMap) {
680        if (appAidInfo.element.GetBundleName() == elementName.GetBundleName() &&
681            appAidInfo.element.GetAbilityName() == elementName.GetAbilityName()) {
682            return true;
683        }
684    }
685#ifdef VENDOR_APPLICATIONS_ENABLED
686    return IsHceAppFromVendor(elementName);
687#else
688    return false;
689#endif
690}
691
692void AppDataParser::GetPaymentAbilityInfos(std::vector<AbilityInfo> &paymentAbilityInfos)
693{
694    if (!appListInitDone_) {
695        InfoLog("bundleMgr is null, try to init again.");
696        InitAppList();
697    }
698    for (const AppDataParser::HceAppAidInfo &appAidInfo : g_hceAppAndAidMap) {
699        if (!IsPaymentApp(appAidInfo)) {
700            continue;
701        }
702        AbilityInfo ability;
703        ability.name = appAidInfo.element.GetAbilityName();
704        ability.bundleName = appAidInfo.element.GetBundleName();
705        ability.labelId = appAidInfo.labelId;
706        ability.iconId = appAidInfo.iconId;
707        InfoLog("The bundlename : %{public}s,the labelId : %{public}d,the iconId : %{public}d",
708                ability.bundleName.c_str(), ability.labelId, ability.iconId);
709        paymentAbilityInfos.push_back(ability);
710    }
711
712    for (const AppDataParser::HceAppAidInfo &appAidInfo : g_offHostAppAndAidMap) {
713        AbilityInfo ability;
714        ability.name = appAidInfo.element.GetAbilityName();
715        ability.bundleName = appAidInfo.element.GetBundleName();
716        ability.labelId = appAidInfo.labelId;
717        ability.iconId = appAidInfo.iconId;
718        InfoLog("The bundlename : %{public}s,the labelId : %{public}d,the iconId : %{public}d",
719                ability.bundleName.c_str(), ability.labelId, ability.iconId);
720        paymentAbilityInfos.push_back(ability);
721    }
722#ifdef VENDOR_APPLICATIONS_ENABLED
723    GetPaymentAbilityInfosFromVendor(paymentAbilityInfos);
724#endif
725}
726
727bool AppDataParser::GetBundleInfo(AppExecFwk::BundleInfo &bundleInfo, const std::string &bundleName)
728{
729    if (bundleName.empty()) {
730        InfoLog("sim bundle name is empty.");
731        return false;
732    }
733    sptr<AppExecFwk::IBundleMgr> bundleMgrProxy = GetBundleMgrProxy();
734    if (bundleMgrProxy == nullptr) {
735        ErrorLog("bundleMgrProxy is nullptr.");
736        return false;
737    }
738    bool result = bundleMgrProxy->GetBundleInfo(bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT,
739                                                bundleInfo, USER_ID);
740    InfoLog("get bundle %{public}s result %{public}d ", bundleName.c_str(), result);
741    if (!result) {
742        ErrorLog("get bundle %{public}s failed ", bundleName.c_str());
743        return false;
744    }
745    return true;
746}
747
748bool AppDataParser::IsSystemApp(uint32_t uid)
749{
750    sptr<AppExecFwk::IBundleMgr> bundleMgrProxy = GetBundleMgrProxy();
751    if (bundleMgrProxy == nullptr) {
752        ErrorLog(" bundleMgrProxy is nullptr.");
753        return false;
754    }
755    return bundleMgrProxy->CheckIsSystemAppByUid(uid);
756}
757
758std::string AppDataParser::GetBundleNameByUid(uint32_t uid)
759{
760    auto bundleMgr = GetBundleMgrProxy();
761    if (bundleMgr == nullptr) {
762        ErrorLog("bundleMgr is nullptr.");
763        return std::string();
764    }
765    std::string bundleName;
766    int ret = bundleMgr->GetNameForUid(uid, bundleName);
767    if (ret == ERR_OK) {
768        return bundleName;
769    } else {
770        ErrorLog("GetNameForUid failed, ret = %{public}d.", ret);
771        return std::string();
772    }
773}
774} // namespace NFC
775} // namespace OHOS
776