• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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