1 /*
2  * Copyright (C) 2022-2023 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 #include "tag_ability_dispatcher.h"
16 #include "ability_manager_client.h"
17 #include "app_data_parser.h"
18 #include "external_deps_proxy.h"
19 #include "loghelper.h"
20 #include "nfc_sdk_common.h"
21 #include "vibrator_agent.h"
22 
23 namespace OHOS {
24 namespace NFC {
25 namespace TAG {
26 using OHOS::NFC::KITS::TagTechnology;
27 using OHOS::AppExecFwk::ElementName;
28 
29 const std::string PARAM_ABILITY_APPINFOS = "ohos.ability.params.appInfos";
30 
TagAbilityDispatcher()31 TagAbilityDispatcher::TagAbilityDispatcher()
32 {
33 }
34 
~TagAbilityDispatcher()35 TagAbilityDispatcher::~TagAbilityDispatcher()
36 {
37 }
38 
SetWantExtraParam(std::shared_ptr<KITS::TagInfo> & tagInfo,AAFwk::Want & want)39 void TagAbilityDispatcher::SetWantExtraParam(std::shared_ptr<KITS::TagInfo>& tagInfo, AAFwk::Want &want)
40 {
41     // put extra data for all included technology, extra data used by 3rd party applications.
42     want.SetParam("uid", tagInfo->GetTagUid());
43     want.SetParam("technology", tagInfo->GetTagTechList());
44     want.SetParam("tagRfDiscId", tagInfo->GetTagRfDiscId());
45 
46     std::vector<int> techList = tagInfo->GetTagTechList();
47     for (size_t i = 0; i < techList.size(); i++) {
48         AppExecFwk::PacMap extra = tagInfo->GetTechExtrasByIndex(i);
49         if (techList[i] == static_cast<int>(TagTechnology::NFC_A_TECH)) {
50             want.SetParam(KITS::TagInfo::SAK, extra.GetIntValue(KITS::TagInfo::SAK, 0));
51             want.SetParam(KITS::TagInfo::ATQA, extra.GetStringValue(KITS::TagInfo::ATQA, ""));
52         } else if (techList[i] == static_cast<int>(TagTechnology::NFC_B_TECH)) {
53             want.SetParam(KITS::TagInfo::APP_DATA, extra.GetStringValue(KITS::TagInfo::APP_DATA, ""));
54             want.SetParam(KITS::TagInfo::PROTOCOL_INFO, extra.GetStringValue(KITS::TagInfo::PROTOCOL_INFO, ""));
55         } else if (techList[i] == static_cast<int>(TagTechnology::NFC_F_TECH)) {
56             want.SetParam(KITS::TagInfo::NFCF_SC, extra.GetStringValue(KITS::TagInfo::NFCF_SC, ""));
57             want.SetParam(KITS::TagInfo::NFCF_PMM, extra.GetStringValue(KITS::TagInfo::NFCF_PMM, ""));
58         } else if (techList[i] == static_cast<int>(TagTechnology::NFC_V_TECH)) {
59             want.SetParam(KITS::TagInfo::RESPONSE_FLAGS, extra.GetIntValue(KITS::TagInfo::RESPONSE_FLAGS, 0));
60             want.SetParam(KITS::TagInfo::DSF_ID, extra.GetIntValue(KITS::TagInfo::DSF_ID, 0));
61         } else if (techList[i] == static_cast<int>(TagTechnology::NFC_ISODEP_TECH)) {
62             want.SetParam(KITS::TagInfo::HISTORICAL_BYTES, extra.GetStringValue(KITS::TagInfo::HISTORICAL_BYTES, ""));
63             want.SetParam(KITS::TagInfo::HILAYER_RESPONSE, extra.GetStringValue(KITS::TagInfo::HILAYER_RESPONSE, ""));
64         } else if (techList[i] == static_cast<int>(TagTechnology::NFC_MIFARE_ULTRALIGHT_TECH)) {
65             want.SetParam(KITS::TagInfo::MIFARE_ULTRALIGHT_C_TYPE,
66                 extra.GetBooleanValue(KITS::TagInfo::MIFARE_ULTRALIGHT_C_TYPE, false));
67         } else if (techList[i] == static_cast<int>(TagTechnology::NFC_NDEF_TECH)) {
68             // set ndef message/type/max size/read mode for ndef tag
69             want.SetParam(KITS::TagInfo::NDEF_MSG, extra.GetStringValue(KITS::TagInfo::NDEF_MSG, ""));
70             want.SetParam(KITS::TagInfo::NDEF_FORUM_TYPE, extra.GetIntValue(KITS::TagInfo::NDEF_FORUM_TYPE, 0));
71             want.SetParam(KITS::TagInfo::NDEF_TAG_LENGTH, extra.GetIntValue(KITS::TagInfo::NDEF_TAG_LENGTH, 0));
72             want.SetParam(KITS::TagInfo::NDEF_TAG_MODE, extra.GetIntValue(KITS::TagInfo::NDEF_TAG_MODE, 0));
73         }
74     }
75 }
76 
StartVibratorOnce()77 void TagAbilityDispatcher::StartVibratorOnce()
78 {
79     InfoLog("Start vibrator once.");
80     OHOS::Sensors::StartVibratorOnce(DEFAULT_MOTOR_VIBRATOR_ONCE);
81 }
82 
DispatchTagAbility(std::shared_ptr<KITS::TagInfo> tagInfo,OHOS::sptr<IRemoteObject> tagServiceIface)83 void TagAbilityDispatcher::DispatchTagAbility(std::shared_ptr<KITS::TagInfo> tagInfo,
84                                               OHOS::sptr<IRemoteObject> tagServiceIface)
85 {
86     if (tagInfo == nullptr) {
87         ErrorLog("DispatchTagAbility tagInfo is null");
88         return;
89     }
90     if (tagServiceIface == nullptr) {
91         WarnLog("DispatchTagAbility tagServiceIface is null");
92     }
93 
94     std::vector<int> techList = tagInfo->GetTagTechList();
95     std::vector<ElementName> elements = AppDataParser::GetInstance().GetDispatchTagAppsByTech(techList);
96 #ifdef VENDOR_APPLICATIONS_ENABLED
97     std::vector<ElementName> vendorElements = AppDataParser::GetInstance().GetVendorDispatchTagAppsByTech(techList);
98     if (elements.size() == 0 && vendorElements.size() == 0) {
99         ExternalDepsProxy::GetInstance().PublishNfcNotification(NFC_NO_HAP_SUPPORTED_NOTIFICATION_ID, "", 0);
100         return;
101     }
102 
103     bool isFromVendor = (vendorElements.size() != 0) ? true : false;
104     AAFwk::Want want;
105     std::vector<std::string> vendorElementNameList;
106     for (auto vendorElement : vendorElements) {
107         std::string elementName = vendorElement.GetBundleName() + vendorElement.GetAbilityName();
108         vendorElementNameList.push_back(elementName);
109     }
110 
111     want.SetParam("remoteTagService", tagServiceIface);
112     SetWantExtraParam(tagInfo, want);
113     if ((vendorElementNameList.size() + elements.size()) > TAG_APP_MATCHED_SIZE_SINGLE) {
114         want.SetParam(PARAM_ABILITY_APPINFOS, vendorElementNameList);
115         DispatchAbilityMultiApp(tagInfo, want);
116     } else if (elements.size() == TAG_APP_MATCHED_SIZE_SINGLE) {
117         want.SetElement(elements[0]);
118         DispatchAbilitySingleApp(want);
119     } else if ((vendorElementNameList.size() == TAG_APP_MATCHED_SIZE_SINGLE) && isFromVendor) {
120         want.SetParam(PARAM_ABILITY_APPINFOS, vendorElementNameList);
121         DispatchAbilitySingleApp(want);
122     }
123 #else
124     if (elements.size() == 0) {
125         return;
126     }
127     AAFwk::Want want;
128     want.SetParam("remoteTagService", tagServiceIface);
129     SetWantExtraParam(tagInfo, want);
130     if (elements.size() == TAG_APP_MATCHED_SIZE_SINGLE) {
131         want.SetElement(elements[0]);
132         DispatchAbilitySingleApp(want);
133     } else {
134         DispatchAbilityMultiApp(tagInfo, want);
135     }
136 #endif
137 }
138 
DispatchAbilityMultiApp(std::shared_ptr<KITS::TagInfo> tagInfo,AAFwk::Want & want)139 void TagAbilityDispatcher::DispatchAbilityMultiApp(std::shared_ptr<KITS::TagInfo> tagInfo, AAFwk::Want& want)
140 {
141     InfoLog("DispatchAbilityMultiApp for app");
142     if (tagInfo == nullptr) {
143         ErrorLog("DispatchTagAbility tagInfo is null");
144         return;
145     }
146 
147     // pull multi app page by skill.uris
148     want.SetAction(KITS::ACTION_TAG_FOUND);
149     std::vector<std::string> techArray;
150     const std::string tagTechStr = "tag-tech/"; // exmaple: "tag-tech/NfcA"
151     for (const auto& tagTech : tagInfo->GetTagTechList()) {
152         if (tagTech < static_cast<int>(TagTechnology::NFC_A_TECH) ||
153             tagTech > static_cast<int>(TagTechnology::NFC_MIFARE_ULTRALIGHT_TECH)) {
154             WarnLog("DispatchAbilityMultiApp tagTech(%{public}d) out of range. ", tagTech);
155             continue;
156         }
157         techArray.push_back(tagTechStr + KITS::TagInfo::GetStringTech(tagTech));
158     }
159     want.SetParam(AAFwk::Want::PARAM_ABILITY_URITYPES, techArray);
160 
161     if (AAFwk::AbilityManagerClient::GetInstance() == nullptr) {
162         ErrorLog("DispatchAbilityMultiApp AbilityManagerClient is null");
163         return;
164     }
165 
166     AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want);
167     InfoLog("DispatchAbilityMultiApp call StartAbility end.");
168 }
169 
DispatchAppGallery(OHOS::sptr<IRemoteObject> tagServiceIface,std::string appGalleryBundleName)170 void TagAbilityDispatcher::DispatchAppGallery(OHOS::sptr<IRemoteObject> tagServiceIface,
171                                               std::string appGalleryBundleName)
172 {
173     InfoLog("DispatchAppGallery appGalleryBundleName = %{public}s", appGalleryBundleName.c_str());
174     AAFwk::Want want;
175     const std::string ABILITY_NAME = "MainAbility";
176     want.SetParam("remoteTagService", tagServiceIface);
177     want.SetElementName(appGalleryBundleName, ABILITY_NAME);
178     DispatchAbilitySingleApp(want);
179 }
180 
DispatchAbilitySingleApp(AAFwk::Want & want)181 void TagAbilityDispatcher::DispatchAbilitySingleApp(AAFwk::Want& want)
182 {
183     if (AAFwk::AbilityManagerClient::GetInstance() == nullptr) {
184         ErrorLog("DispatchAbilitySingleApp AbilityManagerClient is null");
185         return;
186     }
187     AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want);
188     InfoLog("DispatchAbilitySingleApp call StartAbility end.");
189 }
190 }  // namespace TAG
191 }  // namespace NFC
192 }  // namespace OHOS
193