• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "common_event_handler.h"
17 #include "common_event_manager.h"
18 #include "iservice_registry.h"
19 #include "system_ability_definition.h"
20 #include "accesstoken_kit.h"
21 #include "permission_tools.h"
22 
23 namespace OHOS {
24 namespace NFC {
25 const std::string KEY_TAG_TECH = "tag-tech";
26 const std::string KEY_PAYMENT_AID = "payment-aid";
27 const std::string KEY_OHTER_AID = "other-aid";
28 const int USER_ID = 100;
29 sptr<AppExecFwk::IBundleMgr> bundleMgrProxy_;
30 static AppDataParser appDataParser_;
31 
AppDataParser()32 AppDataParser::AppDataParser()
33 {
34     g_tagAppAndTechMap.clear();
35     g_hceAppAndAidMap.clear();
36 }
37 
~AppDataParser()38 AppDataParser::~AppDataParser()
39 {
40 }
41 
GetInstance()42 AppDataParser& AppDataParser::GetInstance()
43 {
44     return appDataParser_;
45 }
46 
GetBundleMgrProxy()47 sptr<AppExecFwk::IBundleMgr> AppDataParser::GetBundleMgrProxy()
48 {
49     sptr<ISystemAbilityManager> systemAbilityManager =
50         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
51     if (!systemAbilityManager) {
52         ErrorLog("GetBundleMgrProxy, systemAbilityManager is null");
53         return nullptr;
54     }
55     sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
56     if (!remoteObject) {
57         ErrorLog("GetBundleMgrProxy, remoteObject is null");
58         return nullptr;
59     }
60     return iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
61 }
62 
HandleAppAddOrChangedEvent(std::shared_ptr<EventFwk::CommonEventData> data)63 void AppDataParser::HandleAppAddOrChangedEvent(std::shared_ptr<EventFwk::CommonEventData> data)
64 {
65     if (data == nullptr) {
66         ErrorLog("HandleAppAddOrChangedEvent, invalid data.");
67         return;
68     }
69     ElementName element = data->GetWant().GetElement();
70     std::string bundleName = element.GetBundleName();
71     if (bundleName.empty()) {
72         ErrorLog("HandleAppAddOrChangedEvent, invaid bundleName.");
73         return;
74     }
75     DebugLog("HandleAppAddOrChangedEvent bundlename: %{public}s", bundleName.c_str());
76     UpdateAppListInfo(element, KITS::ACTION_TAG_FOUND);
77     UpdateAppListInfo(element, KITS::ACTION_HOST_APDU_SERVICE);
78 }
79 
HandleAppRemovedEvent(std::shared_ptr<EventFwk::CommonEventData> data)80 void AppDataParser::HandleAppRemovedEvent(std::shared_ptr<EventFwk::CommonEventData> data)
81 {
82     if (data == nullptr) {
83         ErrorLog("HandleAppRemovedEvent, invalid data.");
84         return;
85     }
86     ElementName element = data->GetWant().GetElement();
87     std::string bundleName = element.GetBundleName();
88     if (bundleName.empty()) {
89         ErrorLog("HandleAppRemovedEvent, invalid bundleName.");
90         return;
91     }
92     DebugLog("HandleAppRemovedEvent, bundleName %{public}s tag size %{public}zu, hce size %{public}zu",
93         bundleName.c_str(),
94         g_tagAppAndTechMap.size(),
95         g_hceAppAndAidMap.size());
96     RemoveTagAppInfo(element);
97     RemoveHceAppInfo(element);
98 }
99 
VerifyHapPermission(const std::string bundleName,const std::string action)100 bool AppDataParser::VerifyHapPermission(const std::string bundleName, const std::string action)
101 {
102     std::string permissionNfc;
103     OHOS::Security::AccessToken::AccessTokenID tokenID;
104     std::map<std::string, std::string> permissionMap = {
105         {KITS::ACTION_TAG_FOUND, TAG_PERM},
106         {KITS::ACTION_HOST_APDU_SERVICE, CARD_EMU_PERM}
107     };
108     std::map<std::string, std::string>::iterator it = permissionMap.find(action.c_str());
109     if (it != permissionMap.end()) {
110         permissionNfc = it->second;
111     } else {
112         ErrorLog("VerifyHapPermission, action no in map!");
113         return false;
114     }
115     tokenID= OHOS::Security::AccessToken::AccessTokenKit::GetHapTokenID(USER_ID, bundleName, 0);
116     int result = OHOS::Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenID, permissionNfc);
117     if (result != OHOS::Security::AccessToken::PERMISSION_GRANTED) {
118         ErrorLog("bundleName %{public}s no permission %{public}s", bundleName.c_str(), permissionNfc.c_str());
119         return false;
120     }
121     return true;
122 }
123 
QueryAbilityInfos(const std::string action,std::vector<AbilityInfo> & abilityInfos,std::vector<ExtensionAbilityInfo> & extensionInfos)124 void AppDataParser::QueryAbilityInfos(const std::string action, std::vector<AbilityInfo> &abilityInfos,
125     std::vector<ExtensionAbilityInfo> &extensionInfos)
126 {
127     if (bundleMgrProxy_ == nullptr) {
128         bundleMgrProxy_ = GetBundleMgrProxy();
129     }
130     if (bundleMgrProxy_ == nullptr) {
131         ErrorLog("QueryAbilityInfos, bundleMgrProxy_ is nullptr.");
132         return;
133     }
134     AAFwk::Want want;
135     want.SetAction(action);
136     want.SetType("*/*"); // skip the type, matched action only.
137     bool withDefault = false;
138     auto abilityInfoFlag = AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_DEFAULT
139         | AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_SKILL_URI;
140     if (!bundleMgrProxy_->ImplicitQueryInfos(want, abilityInfoFlag, USER_ID, withDefault,
141         abilityInfos, extensionInfos)) {
142         WarnLog("QueryAbilityInfos, query none for action %{public}s", action.c_str());
143         return;
144     }
145 }
146 
UpdateAppListInfo(ElementName & element,const std::string action)147 bool AppDataParser::UpdateAppListInfo(ElementName &element, const std::string action)
148 {
149     if (action.compare(KITS::ACTION_TAG_FOUND) != 0 && action.compare(KITS::ACTION_HOST_APDU_SERVICE) != 0) {
150         ErrorLog("UpdateAppListInfo, ignore action = %{public}s", action.c_str());
151         return false;
152     }
153     std::string bundleName = element.GetBundleName();
154     if (!VerifyHapPermission(bundleName, action)) {
155         ErrorLog("Hap have no permission for action = %{public}s", action.c_str());
156         return false;
157     }
158 
159     // query the applications infos that're matched with the acitons.
160     std::vector<AbilityInfo> abilityInfos;
161     std::vector<ExtensionAbilityInfo> extensionAbilityInfos;
162     QueryAbilityInfos(action, abilityInfos, extensionAbilityInfos);
163     for (auto& abilityInfo : abilityInfos) {
164         if (bundleName.empty() || bundleName.compare(abilityInfo.bundleName) != 0) {
165             continue;
166         }
167         if (action.compare(KITS::ACTION_TAG_FOUND) == 0) {
168             UpdateTagAppList(abilityInfo, element);
169         }
170         if (action.compare(KITS::ACTION_HOST_APDU_SERVICE) == 0) {
171             UpdateHceAppList(abilityInfo, element);
172         }
173     }
174     return true;
175 }
176 
InitAppListByAction(const std::string action)177 bool AppDataParser::InitAppListByAction(const std::string action)
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     if (KITS::ACTION_TAG_FOUND.compare(action) == 0) {
184         for (auto& abilityInfo : abilityInfos) {
185             ElementName element(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name,
186                 abilityInfo.moduleName);
187             UpdateTagAppList(abilityInfo, element);
188         }
189     } else if (KITS::ACTION_HOST_APDU_SERVICE.compare(action) == 0) {
190         for (auto& abilityInfo : abilityInfos) {
191             ElementName element(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name,
192                 abilityInfo.moduleName);
193             UpdateHceAppList(abilityInfo, element);
194         }
195     } else {
196         WarnLog("InitAppListByAction,unknown action = %{public}s", action.c_str());
197     }
198     return true;
199 }
200 
IsMatchedByBundleName(ElementName & src,ElementName & target)201 bool AppDataParser::IsMatchedByBundleName(ElementName &src, ElementName &target)
202 {
203     if (src.GetBundleName().compare(target.GetBundleName()) == 0) {
204         return true;
205     }
206     return false;
207 }
208 
GetMatchedTagKeyElement(ElementName & element)209 ElementName AppDataParser::GetMatchedTagKeyElement(ElementName &element)
210 {
211     ElementName emptyElement;
212     std::vector<TagAppTechInfo>::iterator iter;
213     for (iter = g_tagAppAndTechMap.begin(); iter != g_tagAppAndTechMap.end(); ++iter) {
214         if (IsMatchedByBundleName(element, (*iter).element)) {
215             return (*iter).element;
216         }
217     }
218     return emptyElement;
219 }
220 
GetMatchedHceKeyElement(ElementName & element)221 ElementName AppDataParser::GetMatchedHceKeyElement(ElementName &element)
222 {
223     ElementName emptyElement;
224     std::vector<HceAppAidInfo>::iterator iter;
225     for (iter = g_hceAppAndAidMap.begin(); iter != g_hceAppAndAidMap.end(); ++iter) {
226         if (IsMatchedByBundleName(element, (*iter).element)) {
227             return (*iter).element;
228         }
229     }
230     return emptyElement;
231 }
232 
UpdateTagAppList(AbilityInfo & abilityInfo,ElementName & element)233 void AppDataParser::UpdateTagAppList(AbilityInfo &abilityInfo, ElementName &element)
234 {
235     if (!GetMatchedTagKeyElement(element).GetBundleName().empty()) {
236         WarnLog("UpdateTagAppList, rm duplicated app %{public}s", element.GetBundleName().c_str());
237         RemoveTagAppInfo(element);
238     }
239     std::vector<std::string> valueList;
240     for (auto& data : abilityInfo.metadata) {
241         if (KEY_TAG_TECH.compare(data.name) == 0) {
242             valueList.emplace_back(data.value);
243             DebugLog("UpdateTagAppList from metadata, push tech %{public}s", data.value.c_str());
244         }
245     }
246     for (auto& data : abilityInfo.metaData.customizeData) {
247         if (KEY_TAG_TECH.compare(data.name) == 0) {
248             valueList.emplace_back(data.value);
249             DebugLog("UpdateTagAppList from customizeData, push tech %{public}s", data.value.c_str());
250         }
251     }
252     for (auto& uri : abilityInfo.skillUri) {
253         if (uri.type.empty()) {
254             continue;
255         }
256         // format example: "type": "tag-tech/NfcA"
257         auto pos = uri.type.find("/");
258         if (pos == std::string::npos) {
259             ErrorLog("UpdateTagAppList from skillUri, separator not found %{public}s", uri.type.c_str());
260             continue;
261         }
262         std::string tech = uri.type.substr(0, pos);
263         if (KEY_TAG_TECH.compare(tech) != 0) {
264             ErrorLog("UpdateTagAppList KEY_TAG_TECH for %{public}s", tech.c_str());
265             continue;
266         }
267         std::string nfcType = uri.type.substr(pos + 1, uri.type.size());
268         if (std::find(valueList.begin(), valueList.end(), nfcType) == valueList.end()) {
269             valueList.emplace_back(nfcType);
270             DebugLog("UpdateTagAppList from skillUri, push tech %{public}s", nfcType.c_str());
271         }
272     }
273 
274     if (valueList.empty()) {
275         DebugLog("UpdateTagAppList, ignore for app %{public}s %{public}s", element.GetBundleName().c_str(),
276             element.GetAbilityName().c_str());
277         return;
278     }
279 
280     TagAppTechInfo tagAppTechInfo;
281     tagAppTechInfo.element = element;
282     tagAppTechInfo.tech = valueList;
283     g_tagAppAndTechMap.push_back(tagAppTechInfo);
284     DebugLog("UpdateTagAppList, push for app %{public}s %{public}s", element.GetBundleName().c_str(),
285         element.GetAbilityName().c_str());
286 }
287 
UpdateHceAppList(AbilityInfo & abilityInfo,ElementName & element)288 void AppDataParser::UpdateHceAppList(AbilityInfo &abilityInfo, ElementName &element)
289 {
290     if (!GetMatchedHceKeyElement(element).GetBundleName().empty()) {
291         WarnLog("UpdateHceAppList, rm duplicated app %{public}s", element.GetBundleName().c_str());
292         RemoveHceAppInfo(element);
293     }
294     std::vector<AppDataParser::AidInfo> customDataAidList;
295     AppDataParser::AidInfo customDataAid;
296     for (auto& data : abilityInfo.metadata) {
297         if ((KEY_PAYMENT_AID.compare(data.name) == 0) || (KEY_OHTER_AID.compare(data.name) == 0)) {
298             customDataAid.name = data.name;
299             customDataAid.value = data.value;
300             customDataAidList.emplace_back(customDataAid);
301             DebugLog("UpdateHceAppList from metadata, push aid %{public}s", data.value.c_str());
302         }
303     }
304     for (auto& data : abilityInfo.metaData.customizeData) {
305         if ((KEY_PAYMENT_AID.compare(data.name) == 0) || (KEY_OHTER_AID.compare(data.name) == 0)) {
306             customDataAid.name = data.name;
307             customDataAid.value = data.value;
308             customDataAidList.emplace_back(customDataAid);
309             DebugLog("UpdateHceAppList from customizeData, push aid %{public}s", data.value.c_str());
310         }
311     }
312     if (customDataAidList.empty()) {
313         DebugLog("UpdateHceAppList, ignore for app %{public}s %{public}s", element.GetBundleName().c_str(),
314             element.GetAbilityName().c_str());
315         return;
316     }
317     HceAppAidInfo hceAppAidInfo;
318     hceAppAidInfo.element = element;
319     hceAppAidInfo.customDataAid = customDataAidList;
320     g_hceAppAndAidMap.push_back(hceAppAidInfo);
321     DebugLog("UpdateHceAppList, push for app %{public}s %{public}s", element.GetBundleName().c_str(),
322         element.GetAbilityName().c_str());
323 }
324 
RemoveTagAppInfo(ElementName & element)325 void AppDataParser::RemoveTagAppInfo(ElementName &element)
326 {
327     ElementName keyElement = GetMatchedTagKeyElement(element);
328     if (keyElement.GetBundleName().empty()) {
329         WarnLog("RemoveTagAppInfo, keyElement is none, ignore it.");
330         return;
331     }
332     DebugLog("RemoveTagAppInfo, request app %{public}s", keyElement.GetBundleName().c_str());
333     std::vector<TagAppTechInfo>::iterator iter;
334     for (iter = g_tagAppAndTechMap.begin(); iter != g_tagAppAndTechMap.end(); ++iter) {
335         // compare only bundle name to remote the app.
336         if (IsMatchedByBundleName(element, (*iter).element)) {
337             DebugLog("RemoveTagAppInfo, erase app %{public}s", keyElement.GetBundleName().c_str());
338             g_tagAppAndTechMap.erase(iter);
339             break;
340         }
341     }
342 }
343 
RemoveHceAppInfo(ElementName & element)344 void AppDataParser::RemoveHceAppInfo(ElementName &element)
345 {
346     ElementName keyElement = GetMatchedHceKeyElement(element);
347     if (keyElement.GetBundleName().empty()) {
348         WarnLog("RemoveHceAppInfo, keyElement is none, ignore it.");
349         return;
350     }
351     DebugLog("RemoveHceAppInfo, app %{public}s", keyElement.GetBundleName().c_str());
352     std::vector<HceAppAidInfo>::iterator iter;
353     for (iter = g_hceAppAndAidMap.begin(); iter != g_hceAppAndAidMap.end(); ++iter) {
354         // compare only bundle name to remote the app.
355         if (IsMatchedByBundleName(element, (*iter).element)) {
356             DebugLog("RemoveHceAppInfo, erase app %{public}s", keyElement.GetBundleName().c_str());
357             g_hceAppAndAidMap.erase(iter);
358             break;
359         }
360     }
361 }
362 
InitAppList()363 void AppDataParser::InitAppList()
364 {
365     bundleMgrProxy_ = GetBundleMgrProxy();
366     if (!bundleMgrProxy_) {
367         ErrorLog("InitAppList, bundleMgrProxy_ is nullptr.");
368         return;
369     }
370     InitAppListByAction(KITS::ACTION_TAG_FOUND);
371     InitAppListByAction(KITS::ACTION_HOST_APDU_SERVICE);
372     DebugLog("InitAppList, tag size %{public}zu, hce size %{public}zu", g_tagAppAndTechMap.size(),
373         g_hceAppAndAidMap.size());
374 }
375 
GetDispatchTagAppsByTech(std::vector<int> discTechList)376 std::vector<ElementName> AppDataParser::GetDispatchTagAppsByTech(std::vector<int> discTechList)
377 {
378     std::vector<ElementName> elements;
379     for (size_t i = 0; i < discTechList.size(); i++) {
380         std::string discStrTech = KITS::TagInfo::GetStringTech(discTechList[i]);
381         DebugLog("GetDispatchTagAppsByTech, tag size = %{public}zu", g_tagAppAndTechMap.size());
382         if (discStrTech.empty()) {
383             continue;
384         }
385 
386         // parse for all installed app that can handle this technology.
387         std::vector<TagAppTechInfo>::iterator iter;
388         for (iter = g_tagAppAndTechMap.begin(); iter != g_tagAppAndTechMap.end(); ++iter) {
389             bool appExisted = false;
390             for (auto item : elements) {
391                 if (IsMatchedByBundleName(item, (*iter).element)) {
392                     appExisted = true;
393                     break;
394                 }
395             }
396             if (appExisted) {
397                 continue;
398             }
399 
400             std::vector<std::string> vectorTech = (*iter).tech;
401             for (size_t i = 0; i < vectorTech.size(); i++) {
402                 DebugLog("GetDispatchTagAppsByTech, cmp tech %{public}s vs %{public}s",
403                     discStrTech.c_str(), vectorTech[i].c_str());
404                 if (discStrTech.compare(vectorTech[i]) == 0) {
405                     elements.push_back((*iter).element);
406                     break;
407                 }
408             }
409         }
410     }
411     return elements;
412 }
413 }  // namespace NFC
414 }  // namespace OHOS
415