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
22 namespace OHOS {
23 namespace NFC {
NfcPollingManager(std::weak_ptr<NfcService> nfcService,std::weak_ptr<NCI::INciNfccInterface> nciNfccProxy,std::weak_ptr<NCI::INciTagInterface> nciTagProxy)24 NfcPollingManager::NfcPollingManager(std::weak_ptr<NfcService> nfcService,
25 std::weak_ptr<NCI::INciNfccInterface> nciNfccProxy,
26 std::weak_ptr<NCI::INciTagInterface> nciTagProxy)
27 : nfcService_(nfcService), nciNfccProxy_(nciNfccProxy), nciTagProxy_(nciTagProxy)
28 {
29 foregroundData_ = std::make_shared<NfcPollingManager::ForegroundRegistryData>();
30 readerModeData_ = std::make_shared<NfcPollingManager::ReaderModeRegistryData>();
31 currPollingParams_ = NfcPollingParams::GetNfcOffParameters();
32 }
33
~NfcPollingManager()34 NfcPollingManager::~NfcPollingManager()
35 {
36 foregroundData_ = nullptr;
37 readerModeData_ = nullptr;
38 currPollingParams_ = nullptr;
39 }
40
ResetCurrPollingParams()41 void NfcPollingManager::ResetCurrPollingParams()
42 {
43 currPollingParams_ = std::make_shared<NfcPollingParams>();
44 }
45
GetForegroundData()46 std::shared_ptr<NfcPollingManager::ForegroundRegistryData> NfcPollingManager::GetForegroundData()
47 {
48 std::lock_guard<std::mutex> lock(mutex_);
49 return foregroundData_;
50 }
51
GetReaderModeData()52 std::shared_ptr<NfcPollingManager::ReaderModeRegistryData> NfcPollingManager::GetReaderModeData()
53 {
54 std::lock_guard<std::mutex> lock(mutex_);
55 return readerModeData_;
56 }
57
GetCurrentParameters()58 std::shared_ptr<NfcPollingParams> NfcPollingManager::GetCurrentParameters()
59 {
60 std::lock_guard<std::mutex> lock(mutex_);
61 return currPollingParams_;
62 }
63
GetPollingParameters(int screenState)64 std::shared_ptr<NfcPollingParams> NfcPollingManager::GetPollingParameters(int screenState)
65 {
66 // Recompute polling parameters based on screen state
67 std::shared_ptr<NfcPollingParams> params = std::make_shared<NfcPollingParams>();
68
69 if (readerModeData_->isEnabled_) {
70 params->SetTechMask(readerModeData_->techMask_);
71 params->SetEnableReaderMode(true);
72 } else {
73 params->SetTechMask(NfcPollingParams::NFC_POLL_DEFAULT);
74 params->SetEnableReaderMode(false);
75 }
76 return params;
77 }
78
StartPollingLoop(bool force)79 void NfcPollingManager::StartPollingLoop(bool force)
80 {
81 InfoLog("StartPollingLoop force = %{public}d", force);
82 if (nfcService_.expired()) {
83 ErrorLog("StartPollingLoop: nfcService_ is nullptr.");
84 return;
85 }
86 if (!nfcService_.lock()->IsNfcEnabled()) {
87 ErrorLog("StartPollingLoop: NFC not enabled, do not Compute Routing Params.");
88 return;
89 }
90 std::lock_guard<std::mutex> lock(mutex_);
91
92 NfcWatchDog pollingWatchDog("StartPollingLoop", WAIT_MS_SET_ROUTE, nciNfccProxy_);
93 pollingWatchDog.Run();
94 // Compute new polling parameters
95 std::shared_ptr<NfcPollingParams> newParams = GetPollingParameters(screenState_);
96 InfoLog("newParams: %{public}s", newParams->ToString().c_str());
97 InfoLog("currParams: %{public}s", currPollingParams_->ToString().c_str());
98 if (force || !(newParams == currPollingParams_)) {
99 if (newParams->ShouldEnablePolling()) {
100 bool shouldRestart = currPollingParams_->ShouldEnablePolling();
101 InfoLog("StartPollingLoop shouldRestart = %{public}d", shouldRestart);
102
103 nciNfccProxy_.lock()->EnableDiscovery(newParams->GetTechMask(),
104 newParams->ShouldEnableReaderMode(),
105 newParams->ShouldEnableHostRouting(),
106 shouldRestart || force);
107 } else {
108 nciNfccProxy_.lock()->DisableDiscovery();
109 }
110 currPollingParams_ = newParams;
111 } else {
112 InfoLog("StartPollingLoop: polling params equal, not updating");
113 }
114 pollingWatchDog.Cancel();
115 }
116
HandleScreenChanged(int screenState)117 void NfcPollingManager::HandleScreenChanged(int screenState)
118 {
119 std::lock_guard<std::mutex> lock(mutex_);
120 screenState_ = screenState;
121 InfoLog("Screen changed screenState %{public}d", screenState_);
122 if (nciTagProxy_.expired() || nciNfccProxy_.expired()) {
123 ErrorLog("nci proxy nullptr");
124 return;
125 }
126 nciTagProxy_.lock()->StopFieldChecking();
127 nciNfccProxy_.lock()->SetScreenStatus(screenState_);
128 }
129
HandlePackageUpdated(std::shared_ptr<EventFwk::CommonEventData> data)130 bool NfcPollingManager::HandlePackageUpdated(std::shared_ptr<EventFwk::CommonEventData> data)
131 {
132 std::lock_guard<std::mutex> lock(mutex_);
133 std::string action = data->GetWant().GetAction();
134 if (action.empty()) {
135 ErrorLog("action is empty");
136 return false;
137 }
138 if ((action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED) ||
139 (action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED)) {
140 return ExternalDepsProxy::GetInstance().HandleAppAddOrChangedEvent(data);
141 } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED) {
142 return ExternalDepsProxy::GetInstance().HandleAppRemovedEvent(data);
143 } else {
144 DebugLog("not need event.");
145 return false;
146 }
147 }
148
EnableForegroundDispatch(AppExecFwk::ElementName & element,const std::vector<uint32_t> & discTech,const sptr<KITS::IForegroundCallback> & callback)149 bool NfcPollingManager::EnableForegroundDispatch(AppExecFwk::ElementName &element,
150 const std::vector<uint32_t> &discTech, const sptr<KITS::IForegroundCallback> &callback)
151 {
152 if (nfcService_.expired() || nciTagProxy_.expired()) {
153 ErrorLog("EnableForegroundDispatch: nfcService_ is nullptr.");
154 return false;
155 }
156 if (!nfcService_.lock()->IsNfcEnabled()) {
157 ErrorLog("EnableForegroundDispatch: NFC not enabled, do not set foreground");
158 return false;
159 }
160 if (callback == nullptr) {
161 ErrorLog("EnableForegroundDispatch: ForegroundCallback invalid");
162 return false;
163 }
164 bool isDisablePolling = (discTech.size() == 0);
165 DebugLog("EnableForegroundDispatch: element: %{public}s/%{public}s",
166 element.GetBundleName().c_str(), element.GetAbilityName().c_str());
167 if (!isDisablePolling) {
168 foregroundData_->isEnabled_ = true;
169 foregroundData_->techMask_ = nciTagProxy_.lock()->GetTechMaskFromTechList(discTech);
170 foregroundData_->element_ = element;
171 foregroundData_->callback_ = callback;
172 nciNfccProxy_.lock()->NotifyMessageToVendor(KITS::FOREGROUND_APP_KEY, element.GetBundleName());
173 }
174 return true;
175 }
176
DisableForegroundDispatch(const AppExecFwk::ElementName & element)177 bool NfcPollingManager::DisableForegroundDispatch(const AppExecFwk::ElementName &element)
178 {
179 DebugLog("DisableForegroundDispatch: element: %{public}s/%{public}s",
180 element.GetBundleName().c_str(), element.GetAbilityName().c_str());
181 foregroundData_->isEnabled_ = false;
182 foregroundData_->techMask_ = 0xFFFF;
183 foregroundData_->callerToken_ = 0;
184 foregroundData_->callback_ = nullptr;
185 if (nciNfccProxy_.expired()) {
186 ErrorLog("DisableForegroundDispatch: nciNfccProxy_ is nullptr.");
187 return false;
188 }
189 nciNfccProxy_.lock()->NotifyMessageToVendor(KITS::FOREGROUND_APP_KEY, "");
190 return true;
191 }
192
DisableForegroundByDeathRcpt()193 bool NfcPollingManager::DisableForegroundByDeathRcpt()
194 {
195 return DisableForegroundDispatch(foregroundData_->element_);
196 }
197
IsForegroundEnabled()198 bool NfcPollingManager::IsForegroundEnabled()
199 {
200 return foregroundData_->isEnabled_;
201 }
202
SendTagToForeground(KITS::TagInfoParcelable * tagInfo)203 void NfcPollingManager::SendTagToForeground(KITS::TagInfoParcelable* tagInfo)
204 {
205 if (!IsForegroundEnabled() || foregroundData_->callback_ == nullptr) {
206 ErrorLog("SendTagToForeground: invalid foreground state");
207 return;
208 }
209 DebugLog("SendTagToForeground: OnTagDiscovered, tagInfo = %{public}s", tagInfo->ToString().c_str());
210 foregroundData_->callback_->OnTagDiscovered(tagInfo);
211 }
212
EnableReaderMode(AppExecFwk::ElementName & element,std::vector<uint32_t> & discTech,const sptr<KITS::IReaderModeCallback> & callback)213 bool NfcPollingManager::EnableReaderMode(AppExecFwk::ElementName &element, std::vector<uint32_t> &discTech,
214 const sptr<KITS::IReaderModeCallback> &callback)
215 {
216 if (nfcService_.expired() || nciTagProxy_.expired()) {
217 ErrorLog("EnableReaderMode: nfcService_ is nullptr.");
218 return false;
219 }
220 if (!nfcService_.lock()->IsNfcEnabled()) {
221 ErrorLog("EnableReaderMode: NFC not enabled, do not set reader mode");
222 return false;
223 }
224 if (callback == nullptr) {
225 ErrorLog("EnableReaderMode: ReaderModeCallback invalid");
226 return false;
227 }
228 bool isDisablePolling = (discTech.size() == 0);
229 DebugLog("EnableReaderMode: element: %{public}s/%{public}s",
230 element.GetBundleName().c_str(), element.GetAbilityName().c_str());
231 if (!isDisablePolling) {
232 readerModeData_->isEnabled_ = true;
233 readerModeData_->techMask_ = nciTagProxy_.lock()->GetTechMaskFromTechList(discTech);
234 readerModeData_->element_ = element;
235 readerModeData_->callback_ = callback;
236 nciNfccProxy_.lock()->NotifyMessageToVendor(KITS::READERMODE_APP_KEY, element.GetBundleName());
237 }
238 nciTagProxy_.lock()->StopFieldChecking();
239 StartPollingLoop(true);
240 return true;
241 }
242
DisableReaderMode(AppExecFwk::ElementName & element)243 bool NfcPollingManager::DisableReaderMode(AppExecFwk::ElementName &element)
244 {
245 DebugLog("DisableReaderMode: element: %{public}s/%{public}s",
246 element.GetBundleName().c_str(), element.GetAbilityName().c_str());
247 readerModeData_->isEnabled_ = false;
248 readerModeData_->techMask_ = 0xFFFF;
249 readerModeData_->callerToken_ = 0;
250 readerModeData_->callback_ = nullptr;
251 nciTagProxy_.lock()->StopFieldChecking();
252 StartPollingLoop(true);
253 nciNfccProxy_.lock()->NotifyMessageToVendor(KITS::READERMODE_APP_KEY, "");
254 return true;
255 }
256
DisableReaderModeByDeathRcpt()257 bool NfcPollingManager::DisableReaderModeByDeathRcpt()
258 {
259 return DisableReaderMode(readerModeData_->element_);
260 }
261
IsReaderModeEnabled()262 bool NfcPollingManager::IsReaderModeEnabled()
263 {
264 return readerModeData_->isEnabled_;
265 }
266
SendTagToReaderApp(KITS::TagInfoParcelable * tagInfo)267 void NfcPollingManager::SendTagToReaderApp(KITS::TagInfoParcelable* tagInfo)
268 {
269 if (!IsReaderModeEnabled() || readerModeData_->callback_ == nullptr) {
270 ErrorLog("SendTagToReaderApp: invalid readermode state");
271 return;
272 }
273 DebugLog("SendTagToReaderApp: OnTagDiscovered, tagInfo = %{public}s", tagInfo->ToString().c_str());
274 readerModeData_->callback_->OnTagDiscovered(tagInfo);
275 }
276 } // namespace NFC
277 } // namespace OHOS