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