1 /*
2 * Copyright (C) 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 "nfc_polling_manager.h"
16 #include "common_event_support.h"
17 #include "loghelper.h"
18 #include "nfc_service.h"
19 #include "nfc_watch_dog.h"
20 #include "external_deps_proxy.h"
21 #include "ability_manager_client.h"
22
23 namespace OHOS {
24 namespace NFC {
NfcPollingManager(std::weak_ptr<NfcService> nfcService,std::weak_ptr<NCI::INciNfccInterface> nciNfccProxy,std::weak_ptr<NCI::INciTagInterface> nciTagProxy)25 NfcPollingManager::NfcPollingManager(std::weak_ptr<NfcService> nfcService,
26 std::weak_ptr<NCI::INciNfccInterface> nciNfccProxy,
27 std::weak_ptr<NCI::INciTagInterface> nciTagProxy)
28 : nfcService_(nfcService), nciNfccProxy_(nciNfccProxy), nciTagProxy_(nciTagProxy)
29 {
30 foregroundData_ = std::make_shared<NfcPollingManager::ForegroundRegistryData>();
31 readerModeData_ = std::make_shared<NfcPollingManager::ReaderModeRegistryData>();
32 currPollingParams_ = NfcPollingParams::GetNfcOffParameters();
33 }
34
~NfcPollingManager()35 NfcPollingManager::~NfcPollingManager()
36 {
37 foregroundData_ = nullptr;
38 readerModeData_ = nullptr;
39 currPollingParams_ = nullptr;
40 }
41
ResetCurrPollingParams()42 void NfcPollingManager::ResetCurrPollingParams()
43 {
44 std::lock_guard<std::mutex> lock(mutex_);
45 currPollingParams_ = std::make_shared<NfcPollingParams>();
46 }
47
GetForegroundData()48 std::shared_ptr<NfcPollingManager::ForegroundRegistryData> NfcPollingManager::GetForegroundData()
49 {
50 std::lock_guard<std::mutex> lock(mutex_);
51 return foregroundData_;
52 }
53
GetReaderModeData()54 std::shared_ptr<NfcPollingManager::ReaderModeRegistryData> NfcPollingManager::GetReaderModeData()
55 {
56 std::lock_guard<std::mutex> lock(mutex_);
57 return readerModeData_;
58 }
59
GetCurrentParameters()60 std::shared_ptr<NfcPollingParams> NfcPollingManager::GetCurrentParameters()
61 {
62 std::lock_guard<std::mutex> lock(mutex_);
63 return currPollingParams_;
64 }
65
GetPollingParameters(int screenState)66 std::shared_ptr<NfcPollingParams> NfcPollingManager::GetPollingParameters(int screenState)
67 {
68 // Recompute polling parameters based on screen state
69 std::shared_ptr<NfcPollingParams> params = std::make_shared<NfcPollingParams>();
70
71 if (readerModeData_->isEnabled_) {
72 params->SetTechMask(readerModeData_->techMask_);
73 params->SetEnableReaderMode(true);
74 } else {
75 params->SetTechMask(NfcPollingParams::NFC_POLL_DEFAULT);
76 params->SetEnableReaderMode(false);
77 }
78 return params;
79 }
80
StartPollingLoop(bool force)81 void NfcPollingManager::StartPollingLoop(bool force)
82 {
83 InfoLog("StartPollingLoop force = %{public}d", force);
84 if (nfcService_.expired()) {
85 ErrorLog("StartPollingLoop: nfcService_ is nullptr.");
86 return;
87 }
88 if (!nfcService_.lock()->IsNfcEnabled()) {
89 ErrorLog("StartPollingLoop: NFC not enabled, do not Compute Routing Params.");
90 return;
91 }
92
93 std::lock_guard<std::mutex> lock(mutex_);
94 NfcWatchDog pollingWatchDog("StartPollingLoop", WAIT_MS_SET_ROUTE, nciNfccProxy_);
95 pollingWatchDog.Run();
96 // Compute new polling parameters
97 std::shared_ptr<NfcPollingParams> newParams = GetPollingParameters(screenState_);
98 InfoLog("newParams: %{public}s", newParams->ToString().c_str());
99 InfoLog("currParams: %{public}s", currPollingParams_->ToString().c_str());
100 if ((force || !(newParams == currPollingParams_)) && !nciNfccProxy_.expired()) {
101 if (newParams->ShouldEnablePolling()) {
102 bool shouldRestart = currPollingParams_->ShouldEnablePolling();
103 InfoLog("StartPollingLoop shouldRestart = %{public}d", shouldRestart);
104
105 nciNfccProxy_.lock()->EnableDiscovery(newParams->GetTechMask(),
106 newParams->ShouldEnableReaderMode(),
107 newParams->ShouldEnableHostRouting(),
108 shouldRestart || force);
109 } else {
110 nciNfccProxy_.lock()->DisableDiscovery();
111 }
112 currPollingParams_ = newParams;
113 } else {
114 InfoLog("StartPollingLoop: polling params equal, not updating");
115 }
116 pollingWatchDog.Cancel();
117 }
118
HandleScreenChanged(int screenState)119 void NfcPollingManager::HandleScreenChanged(int screenState)
120 {
121 std::lock_guard<std::mutex> lock(mutex_);
122 screenState_ = screenState;
123 InfoLog("Screen changed screenState %{public}d", screenState_);
124 if (nciTagProxy_.expired() || nciNfccProxy_.expired()) {
125 ErrorLog("nci proxy nullptr");
126 return;
127 }
128 nciTagProxy_.lock()->StopFieldChecking();
129 nciNfccProxy_.lock()->SetScreenStatus(screenState_);
130 }
131
HandlePackageUpdated(std::shared_ptr<EventFwk::CommonEventData> data)132 bool NfcPollingManager::HandlePackageUpdated(std::shared_ptr<EventFwk::CommonEventData> data)
133 {
134 std::lock_guard<std::mutex> lock(mutex_);
135 if (data == nullptr) {
136 ErrorLog("data is null");
137 return false;
138 }
139 std::string action = data->GetWant().GetAction();
140 if (action.empty()) {
141 ErrorLog("action is empty");
142 return false;
143 }
144 if ((action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED) ||
145 (action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED)) {
146 return ExternalDepsProxy::GetInstance().HandleAppAddOrChangedEvent(data);
147 } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED) {
148 return ExternalDepsProxy::GetInstance().HandleAppRemovedEvent(data);
149 } else {
150 DebugLog("not need event.");
151 return false;
152 }
153 }
154
EnableForegroundDispatch(const AppExecFwk::ElementName & element,const std::vector<uint32_t> & discTech,const sptr<KITS::IForegroundCallback> & callback,bool isVendorApp)155 bool NfcPollingManager::EnableForegroundDispatch(const AppExecFwk::ElementName &element,
156 const std::vector<uint32_t> &discTech, const sptr<KITS::IForegroundCallback> &callback, bool isVendorApp)
157 {
158 if (nfcService_.expired() || nciTagProxy_.expired()) {
159 ErrorLog("EnableForegroundDispatch: nfcService_ is nullptr.");
160 return false;
161 }
162 if (!nfcService_.lock()->IsNfcEnabled()) {
163 ErrorLog("EnableForegroundDispatch: NFC not enabled, do not set foreground");
164 return false;
165 }
166 if (callback == nullptr) {
167 ErrorLog("EnableForegroundDispatch: ForegroundCallback invalid");
168 return false;
169 }
170 bool isDisablePolling = (discTech.size() == 0);
171 DebugLog("EnableForegroundDispatch: element: %{public}s/%{public}s",
172 element.GetBundleName().c_str(), element.GetAbilityName().c_str());
173 if (!isDisablePolling) {
174 {
175 std::lock_guard<std::mutex> lock(mutex_);
176 foregroundData_->isEnabled_ = true;
177 foregroundData_->isVendorApp_ = isVendorApp;
178 foregroundData_->techMask_ = nciTagProxy_.lock()->GetTechMaskFromTechList(discTech);
179 foregroundData_->element_ = element;
180 foregroundData_->callback_ = callback;
181 }
182 if (!nciNfccProxy_.expired()) {
183 nciNfccProxy_.lock()->NotifyMessageToVendor(KITS::FOREGROUND_APP_KEY, element.GetBundleName());
184 }
185 }
186 return true;
187 }
188
DisableForegroundDispatch(const AppExecFwk::ElementName & element)189 bool NfcPollingManager::DisableForegroundDispatch(const AppExecFwk::ElementName &element)
190 {
191 {
192 std::lock_guard<std::mutex> lock(mutex_);
193 DebugLog("DisableForegroundDispatch: element: %{public}s/%{public}s",
194 element.GetBundleName().c_str(), element.GetAbilityName().c_str());
195 foregroundData_->isEnabled_ = false;
196 foregroundData_->isVendorApp_ = false;
197 foregroundData_->techMask_ = 0xFFFF;
198 foregroundData_->callerToken_ = 0;
199 foregroundData_->callback_ = nullptr;
200 }
201 if (!nciNfccProxy_.expired()) {
202 nciNfccProxy_.lock()->NotifyMessageToVendor(KITS::FOREGROUND_APP_KEY, "");
203 }
204 return true;
205 }
206
DisableForegroundByDeathRcpt()207 bool NfcPollingManager::DisableForegroundByDeathRcpt()
208 {
209 return DisableForegroundDispatch(foregroundData_->element_);
210 }
211
IsForegroundEnabled()212 bool NfcPollingManager::IsForegroundEnabled()
213 {
214 std::lock_guard<std::mutex> lock(mutex_);
215 if (foregroundData_ == nullptr) {
216 ErrorLog("foregroundData_ nullptr");
217 return false;
218 }
219 if (!foregroundData_->isEnabled_) {
220 return false;
221 }
222 if (foregroundData_->isVendorApp_) {
223 InfoLog("vendor app, skip foreground check");
224 return true;
225 }
226 std::string bundleName = foregroundData_->element_.GetBundleName();
227 return CheckForegroundApp(bundleName);
228 }
229
SendTagToForeground(KITS::TagInfoParcelable * tagInfo)230 void NfcPollingManager::SendTagToForeground(KITS::TagInfoParcelable* tagInfo)
231 {
232 if (tagInfo == nullptr) {
233 ErrorLog("SendTagToForeground: tagInfo is nullptr");
234 return;
235 }
236 std::lock_guard<std::mutex> lock(mutex_);
237 if (foregroundData_->callback_ == nullptr) {
238 ErrorLog("SendTagToForeground: invalid foreground state");
239 return;
240 }
241 DebugLog("SendTagToForeground: OnTagDiscovered, tagInfo = %{public}s", tagInfo->ToString().c_str());
242 foregroundData_->callback_->OnTagDiscovered(tagInfo);
243 }
244
EnableReaderMode(const AppExecFwk::ElementName & element,const std::vector<uint32_t> & discTech,const sptr<KITS::IReaderModeCallback> & callback,bool isVendorApp)245 bool NfcPollingManager::EnableReaderMode(const AppExecFwk::ElementName &element, const std::vector<uint32_t> &discTech,
246 const sptr<KITS::IReaderModeCallback> &callback, bool isVendorApp)
247 {
248 if (nfcService_.expired() || nciTagProxy_.expired()) {
249 ErrorLog("EnableReaderMode: nfcService_ or nciTagProxy_ is nullptr.");
250 return false;
251 }
252 if (!nfcService_.lock()->IsNfcEnabled()) {
253 ErrorLog("EnableReaderMode: NFC not enabled, do not set reader mode");
254 return false;
255 }
256 if (callback == nullptr) {
257 ErrorLog("EnableReaderMode: ReaderModeCallback invalid");
258 return false;
259 }
260 bool isDisablePolling = (discTech.size() == 0);
261 DebugLog("EnableReaderMode: element: %{public}s/%{public}s",
262 element.GetBundleName().c_str(), element.GetAbilityName().c_str());
263 if (!isDisablePolling) {
264 {
265 std::lock_guard<std::mutex> lock(mutex_);
266 readerModeData_->isEnabled_ = true;
267 readerModeData_->isVendorApp_ = isVendorApp;
268 readerModeData_->techMask_ = nciTagProxy_.lock()->GetTechMaskFromTechList(discTech);
269 readerModeData_->element_ = element;
270 readerModeData_->callback_ = callback;
271 }
272 if (!nciNfccProxy_.expired()) {
273 nciNfccProxy_.lock()->NotifyMessageToVendor(KITS::READERMODE_APP_KEY, element.GetBundleName());
274 }
275 }
276 nciTagProxy_.lock()->StopFieldChecking();
277 StartPollingLoop(true);
278 return true;
279 }
280
DisableReaderMode(const AppExecFwk::ElementName & element)281 bool NfcPollingManager::DisableReaderMode(const AppExecFwk::ElementName &element)
282 {
283 DebugLog("DisableReaderMode: element: %{public}s/%{public}s",
284 element.GetBundleName().c_str(), element.GetAbilityName().c_str());
285 {
286 std::lock_guard<std::mutex> lock(mutex_);
287 readerModeData_->isEnabled_ = false;
288 readerModeData_->isVendorApp_ = false;
289 readerModeData_->techMask_ = 0xFFFF;
290 readerModeData_->callerToken_ = 0;
291 readerModeData_->callback_ = nullptr;
292 }
293 if (!nciTagProxy_.expired()) {
294 nciTagProxy_.lock()->StopFieldChecking();
295 }
296 if (!nciNfccProxy_.expired()) {
297 nciNfccProxy_.lock()->NotifyMessageToVendor(KITS::READERMODE_APP_KEY, "");
298 }
299 StartPollingLoop(true);
300 return true;
301 }
302
DisableReaderModeByDeathRcpt()303 bool NfcPollingManager::DisableReaderModeByDeathRcpt()
304 {
305 return DisableReaderMode(readerModeData_->element_);
306 }
307
IsReaderModeEnabled()308 bool NfcPollingManager::IsReaderModeEnabled()
309 {
310 std::lock_guard<std::mutex> lock(mutex_);
311 if (readerModeData_ == nullptr) {
312 ErrorLog("readerModeData_ nullptr");
313 return false;
314 }
315 if (!readerModeData_->isEnabled_) {
316 return false;
317 }
318 if (readerModeData_->isVendorApp_) {
319 InfoLog("vendor app, skip foreground check");
320 return true;
321 }
322 std::string bundleName = readerModeData_->element_.GetBundleName();
323 return CheckForegroundApp(bundleName);
324 }
325
SendTagToReaderApp(KITS::TagInfoParcelable * tagInfo)326 void NfcPollingManager::SendTagToReaderApp(KITS::TagInfoParcelable* tagInfo)
327 {
328 if (tagInfo == nullptr) {
329 ErrorLog("SendTagToReaderApp: tagInfo is nullptr");
330 return;
331 }
332 std::lock_guard<std::mutex> lock(mutex_);
333 if (readerModeData_->callback_ == nullptr) {
334 ErrorLog("SendTagToReaderApp: invalid readermode state");
335 return;
336 }
337 DebugLog("SendTagToReaderApp: OnTagDiscovered, tagInfo = %{public}s", tagInfo->ToString().c_str());
338 readerModeData_->callback_->OnTagDiscovered(tagInfo);
339 }
340
CheckForegroundApp(const std::string & readerBundle)341 bool NfcPollingManager::CheckForegroundApp(const std::string &readerBundle)
342 {
343 std::vector<AppExecFwk::AbilityStateData> list {};
344 int ret = AAFwk::AbilityManagerClient::GetInstance()->GetForegroundUIAbilities(list);
345 if (ret != ERR_OK) {
346 ErrorLog("GetForegroundUIAbilities failed: %{public}d", ret);
347 return false;
348 }
349 for (auto abilityStateData : list) {
350 std::string bundleName = abilityStateData.bundleName;
351 std::string abilityName = abilityStateData.abilityName;
352 if (abilityStateData.abilityState == static_cast<int32_t>(AAFwk::AbilityState::FOREGROUND)) {
353 InfoLog("fg element: %{public}s/%{public}s", bundleName.c_str(), abilityName.c_str());
354 if (readerBundle == bundleName) {
355 return true;
356 }
357 }
358 }
359 WarnLog("%{public}s not foreground", readerBundle.c_str());
360 return false;
361 }
362
CheckForegroundAbility(const std::string & readerBundle,const std::string & readerAbility)363 bool NfcPollingManager::CheckForegroundAbility(const std::string &readerBundle, const std::string &readerAbility)
364 {
365 std::vector<AppExecFwk::AbilityStateData> list {};
366 int ret = AAFwk::AbilityManagerClient::GetInstance()->GetForegroundUIAbilities(list);
367 if (ret != ERR_OK) {
368 ErrorLog("GetForegroundUIAbilities failed: %{public}d", ret);
369 return false;
370 }
371 for (auto abilityStateData : list) {
372 std::string bundleName = abilityStateData.bundleName;
373 std::string abilityName = abilityStateData.abilityName;
374 if (abilityStateData.abilityState == static_cast<int32_t>(AAFwk::AbilityState::FOREGROUND)) {
375 InfoLog("fg element: %{public}s/%{public}s", bundleName.c_str(), abilityName.c_str());
376 if (readerBundle == bundleName && readerAbility == abilityName) {
377 return true;
378 }
379 }
380 }
381 WarnLog("%{public}s/%{public}s not foreground", readerBundle.c_str(), readerAbility.c_str());
382 return false;
383 }
384 } // namespace NFC
385 } // namespace OHOS