1 /*
2 * Copyright (C) 2024 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 "ndef_har_dispatch.h"
16
17 #include "external_deps_proxy.h"
18 #include "iservice_registry.h"
19 #include "ndef_har_data_parser.h"
20 #include "tag_ability_dispatcher.h"
21 #include "ability_manager_client.h"
22 #include "loghelper.h"
23 #include "bundle_mgr_interface.h"
24 #include "if_system_ability_manager.h"
25
26 namespace OHOS {
27 namespace NFC {
28 namespace TAG {
29 const int USER_ID = 100;
30 const int BUNDLE_MGR_SERVICE_SYS_ABILITY_ID = 401;
31 using namespace OHOS::NFC::KITS;
32
33 std::string uri_ {};
34 std::string browserBundleName_ {};
35
NdefHarDispatch()36 NdefHarDispatch::NdefHarDispatch()
37 {
38 }
39
GetInstance()40 NdefHarDispatch& NdefHarDispatch::GetInstance()
41 {
42 static NdefHarDispatch instance;
43 return instance;
44 }
45
GetBundleMgrProxy()46 sptr<AppExecFwk::IBundleMgr> NdefHarDispatch::GetBundleMgrProxy()
47 {
48 sptr<ISystemAbilityManager> systemAbilityManager =
49 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
50 if (!systemAbilityManager) {
51 ErrorLog("GetBundleMgrProxy, systemAbilityManager is null");
52 return nullptr;
53 }
54 sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
55 if (!remoteObject) {
56 ErrorLog("GetBundleMgrProxy, remoteObject is null");
57 return nullptr;
58 }
59 return iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
60 }
61
62 /* Implicit matching, using mimetype to pull up app */
DispatchMimeType(const std::string & type,std::shared_ptr<KITS::TagInfo> tagInfo)63 bool NdefHarDispatch::DispatchMimeType(const std::string &type, std::shared_ptr<KITS::TagInfo> tagInfo)
64 {
65 if (type.empty() || tagInfo == nullptr) {
66 ErrorLog("NdefHarDispatch::DispatchMimeType type is empty");
67 return false;
68 }
69 AAFwk::Want want;
70 want.SetType(type);
71 ExternalDepsProxy::GetInstance().SetWantExtraParam(tagInfo, want);
72 if (GetBundleMgrProxy() == nullptr) {
73 ErrorLog("NdefHarDispatch::DispatchMimeType GetBundleMgrProxy is nullptr");
74 return false;
75 }
76 bool withDefault = false;
77 auto abilityInfoFlag = AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_DEFAULT
78 | AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_SKILL_URI
79 | AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA;
80 std::vector<AbilityInfo> abilityInfos;
81 std::vector<ExtensionAbilityInfo> extensionInfos;
82 bool findDefaultApp = false;
83 if (!GetBundleMgrProxy()->ImplicitQueryInfos(
84 want, abilityInfoFlag, USER_ID, withDefault, abilityInfos, extensionInfos, findDefaultApp)) {
85 ErrorLog("NdefHarDispatch::DispatchMimeType ImplicitQueryInfos false");
86 return false;
87 }
88 int32_t errCode = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want);
89 if (errCode) {
90 ErrorLog("NdefHarDispatch::DispatchMimeType call StartAbility fail. ret = %{public}d", errCode);
91 return false;
92 }
93 return true;
94 }
95
96 /* Call GetLaunchWantForBundle through bundlename to obtain the want and pull up the app */
DispatchBundleAbility(const std::string & harPackage,std::shared_ptr<KITS::TagInfo> tagInfo,const std::string & mimeType,const std::string & uri)97 bool NdefHarDispatch::DispatchBundleAbility(const std::string &harPackage, std::shared_ptr<KITS::TagInfo> tagInfo,
98 const std::string &mimeType, const std::string &uri)
99 {
100 if (harPackage.empty()) {
101 ErrorLog("NdefHarDispatch::DispatchBundleAbility harPackage is empty");
102 return false;
103 }
104 std::string harPackageString = NfcSdkCommon::HexStringToAsciiString(harPackage);
105 AAFwk::Want want;
106 if (GetBundleMgrProxy() == nullptr) {
107 ErrorLog("NdefHarDispatch::GetBundleMgrProxy is nullptr");
108 return false;
109 }
110 int32_t errCode = GetBundleMgrProxy()->GetLaunchWantForBundle(harPackageString, want, USER_ID);
111 if (errCode) {
112 ErrorLog("NdefHarDispatch::GetLaunchWantForBundle fail. ret = %{public}d, harPackage = %{public}s",
113 errCode, harPackageString.c_str());
114 return false;
115 }
116 if (!mimeType.empty() && tagInfo != nullptr) {
117 want.SetType(mimeType);
118 ExternalDepsProxy::GetInstance().SetWantExtraParam(tagInfo, want);
119 }
120 if (uri.size() > 0) {
121 want.SetUri(uri);
122 }
123 errCode = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want);
124 if (errCode) {
125 ErrorLog("NdefHarDispatch::StartAbility fail. ret = %{public}d, harPackage = %{public}s",
126 errCode, harPackageString.c_str());
127 return false;
128 }
129 return true;
130 }
131
DispatchUriToBundleAbility(const std::string & uri)132 bool NdefHarDispatch::DispatchUriToBundleAbility(const std::string &uri)
133 {
134 if (uri.empty()) {
135 ErrorLog("NdefHarDispatch::DispatchUriToBundleAbility uri is empty");
136 return false;
137 }
138 bool canOpen = false;
139 if (GetBundleMgrProxy() == nullptr) {
140 ErrorLog("NdefHarDispatch::DispatchUriToBundleAbility GetBundleMgrProxy is nullptr");
141 return false;
142 }
143 int32_t errCode = GetBundleMgrProxy()->CanOpenLink(uri, canOpen);
144 if (!errCode && canOpen) {
145 InfoLog("NdefHarDispatch::DispatchUriToBundleAbility CanOpenLink");
146 }
147 ErrorLog("CanOpenLink fail. errCode = %{public}d, canOpen = %{public}d", errCode, canOpen);
148 return false;
149 }
150
151 /* Pulling web page links through browser */
DispatchWebLink(const std::string & webAddress,const std::string & browserBundleName)152 bool NdefHarDispatch::DispatchWebLink(const std::string &webAddress, const std::string &browserBundleName)
153 {
154 std::unique_lock<std::shared_mutex> guard(mutex_);
155 InfoLog("NdefHarDispatch::DispatchWebLink enter");
156 if (webAddress.empty() || browserBundleName.empty()) {
157 ErrorLog("NdefHarDispatch::DispatchWebLink is empty");
158 return false;
159 }
160 uri_ = webAddress;
161 browserBundleName_ = browserBundleName;
162 ExternalDepsProxy::GetInstance().PublishNfcNotification(NFC_BROWSER_NOTIFICATION_ID, uri_, 0);
163 return true;
164 }
165
OnBrowserOpenLink()166 void NdefHarDispatch::OnBrowserOpenLink()
167 {
168 std::unique_lock<std::shared_mutex> guard(mutex_);
169 InfoLog("NdefHarDispatch::OnBrowserOpenLink, %{public}s, %{public}s",
170 NfcSdkCommon::CodeMiddlePart(browserBundleName_).c_str(), NfcSdkCommon::CodeMiddlePart(uri_).c_str());
171 AAFwk::Want want;
172 const std::string ABILITY_NAME = "MainAbility";
173 const std::string ACTION_NAME = "ohos.want.action.viewData";
174 const std::string ENTITY_NAME = "entity.system.browsable";
175 want.SetElementName(browserBundleName_, ABILITY_NAME);
176 want.SetAction(ACTION_NAME);
177 want.SetUri(uri_);
178 want.AddEntity(ENTITY_NAME);
179 int32_t errCode = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want);
180 if (errCode) {
181 ErrorLog("NdefHarDispatch::DispatchWebLink call StartAbility fail. ret = %{public}d", errCode);
182 }
183 }
184 } // namespace TAG
185 } // namespace NFC
186 } // namespace OHOS