1 /*
2 * Copyright (C) 2022 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_service.h"
16 #include <unistd.h>
17 #include "app_data_parser.h"
18 #include "common_event_handler.h"
19 #include "loghelper.h"
20 #include "nfc_controller.h"
21 #include "nfc_polling_params.h"
22 #include "nfc_sdk_common.h"
23 #include "nfc_watch_dog.h"
24 #include "nfcc_host.h"
25 #include "want.h"
26 #include "utils/preferences/nfc_pref_impl.h"
27 #include "tag_session.h"
28
29 namespace OHOS {
30 namespace NFC {
31 const std::u16string NFC_SERVICE_NAME = OHOS::to_utf16("ohos.nfc.service");
32 const int ROUTING_DELAY_TIME = 500; // ms
33
NfcService(std::unique_ptr<NFC::NCI::INfccHost> nfccHost)34 NfcService::NfcService(std::unique_ptr<NFC::NCI::INfccHost> nfccHost)
35 : nfccHost_(std::move(nfccHost)),
36 nfcControllerImpl_(nullptr),
37 eventHandler_(nullptr),
38 tagDispatcher_(nullptr),
39 nfcState_(KITS::STATE_OFF)
40 {
41 }
42
~NfcService()43 NfcService::~NfcService()
44 {
45 nfcControllerImpl_ = nullptr;
46 if (task_ && task_->joinable()) {
47 task_->join();
48 }
49 if (rootTask_ && rootTask_->joinable()) {
50 rootTask_->join();
51 }
52 }
53
GetInstance() const54 std::weak_ptr<NfcService> NfcService::GetInstance() const
55 {
56 return nfcService_;
57 }
58
Initialize()59 bool NfcService::Initialize()
60 {
61 nfcService_ = shared_from_this();
62 InfoLog("Nfc service initialize.");
63 if (nfccHost_) {
64 nfccHost_->SetNfccHostListener(nfcService_);
65 } else {
66 nfccHost_ = std::make_shared<NFC::NCI::NfccHost>(nfcService_);
67 }
68
69 // inner message handler, used by other modules as initialization parameters
70 std::shared_ptr<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create("nfcservice::EventRunner");
71 eventHandler_ = std::make_shared<CommonEventHandler>(runner, shared_from_this());
72 tagDispatcher_ = std::make_shared<TAG::TagDispatcher>(shared_from_this());
73 tagSessionIface_ = new TAG::TagSession(shared_from_this());
74 ceService_ = std::make_shared<CeService>(shared_from_this());
75
76 // To be structured after Tag and HCE, the controller module is the controller of tag and HCE module
77 nfcControllerImpl_ = new NfcControllerImpl(shared_from_this());
78
79 currPollingParams_ = NfcPollingParams::GetNfcOffParameters();
80
81 runner->Run();
82 // NFC ROOT
83 ExecuteTask(KITS::TASK_INITIALIZE);
84 return true;
85 }
86
GetTagDispatcher()87 std::weak_ptr<TAG::TagDispatcher> NfcService::GetTagDispatcher()
88 {
89 return tagDispatcher_;
90 }
91
GetTagServiceIface()92 OHOS::sptr<IRemoteObject> NfcService::GetTagServiceIface()
93 {
94 return tagSessionIface_;
95 }
96
OnTagDiscovered(std::shared_ptr<NCI::ITagHost> tagHost)97 void NfcService::OnTagDiscovered(std::shared_ptr<NCI::ITagHost> tagHost)
98 {
99 InfoLog("NfcService::OnTagDiscovered");
100 eventHandler_->SendEvent<NCI::ITagHost>(static_cast<uint32_t>(NfcCommonEvent::MSG_TAG_FOUND), tagHost);
101 }
102
FieldActivated()103 void NfcService::FieldActivated()
104 {
105 InfoLog("NfcService::FieldActivated");
106 eventHandler_->SendEvent(static_cast<uint32_t>(NfcCommonEvent::MSG_FIELD_ACTIVATED));
107 }
108
FieldDeactivated()109 void NfcService::FieldDeactivated()
110 {
111 InfoLog("NfcService::FiledDeactivated");
112 eventHandler_->SendEvent(static_cast<uint32_t>(NfcCommonEvent::MSG_FIELD_DEACTIVATED));
113 }
114
IsNfcTaskReady(std::future<int> & future) const115 bool NfcService::IsNfcTaskReady(std::future<int>& future) const
116 {
117 if (future.valid()) {
118 if (std::future_status::ready != future.wait_for(std::chrono::seconds(1))) {
119 return false;
120 }
121 }
122 return true;
123 }
124
ExecuteTask(KITS::NfcTask param)125 void NfcService::ExecuteTask(KITS::NfcTask param)
126 {
127 std::lock_guard<std::mutex> lock(mutex_);
128 if (nfcState_ == KITS::STATE_TURNING_OFF || nfcState_ == KITS::STATE_TURNING_ON) {
129 WarnLog("Execute task %{public}d from bad state %{public}d", param, nfcState_);
130 return;
131 }
132
133 // Check the current state
134 if (param == KITS::TASK_TURN_ON && nfcState_ == KITS::STATE_ON) {
135 WarnLog("NFC Turn On, already On");
136 return;
137 }
138 if (param == KITS::TASK_TURN_OFF && nfcState_ == KITS::STATE_OFF) {
139 WarnLog("NFC Turn Off, already Off");
140 return;
141 }
142
143 std::promise<int> promise;
144 if (rootTask_) {
145 if (!IsNfcTaskReady(future_)) {
146 WarnLog("ExecuteTask, IsNfcTaskReady is false.");
147 return;
148 }
149 if (task_ && task_->joinable()) {
150 task_->join();
151 }
152 future_ = promise.get_future();
153 task_ = std::make_unique<std::thread>(&NfcService::NfcTaskThread, this, param, std::move(promise));
154 } else {
155 rootTask_ = std::make_unique<std::thread>(&NfcService::NfcTaskThread, this, param, std::move(promise));
156 }
157 }
158
NfcTaskThread(KITS::NfcTask params,std::promise<int> promise)159 void NfcService::NfcTaskThread(KITS::NfcTask params, std::promise<int> promise)
160 {
161 InfoLog("Nfc task thread params %{public}d", params);
162 switch (params) {
163 case KITS::TASK_TURN_ON:
164 DoTurnOn();
165 break;
166 case KITS::TASK_TURN_OFF:
167 DoTurnOff();
168 break;
169 case KITS::TASK_INITIALIZE:
170 DoInitialize();
171 break;
172 default:
173 break;
174 }
175 promise.set_value_at_thread_exit(0);
176 return;
177 }
178
DoTurnOn()179 bool NfcService::DoTurnOn()
180 {
181 InfoLog("Nfc do turn on: current state %{public}d", nfcState_);
182 UpdateNfcState(KITS::STATE_TURNING_ON);
183
184 NfcWatchDog nfcWatchDog("DoTurnOn", WAIT_MS_INIT, nfccHost_);
185 nfcWatchDog.Run();
186 // Routing WakeLock acquire
187 if (!nfccHost_->Initialize()) {
188 ErrorLog("Nfc do turn on err");
189 UpdateNfcState(KITS::STATE_OFF);
190 // Routing Wake Lock release
191 nfcWatchDog.Cancel();
192 return false;
193 }
194 // Routing Wake Lock release
195 nfcWatchDog.Cancel();
196
197 nciVersion_ = nfccHost_->GetNciVersion();
198 InfoLog("Get nci version: ver %{public}d", nciVersion_);
199
200 UpdateNfcState(KITS::STATE_ON);
201
202 nfccHost_->SetScreenStatus(screenState_);
203
204 /* Start polling loop */
205 StartPollingLoop(true);
206
207 ComputeRoutingParams();
208 CommitRouting();
209
210 return true;
211 }
212
DoTurnOff()213 bool NfcService::DoTurnOff()
214 {
215 InfoLog("Nfc do turn off: current state %{public}d", nfcState_);
216 UpdateNfcState(KITS::STATE_TURNING_OFF);
217
218 /* WatchDog to monitor for Deinitialize failed */
219 NfcWatchDog nfcWatchDog("DoTurnOff", WAIT_MS_SET_ROUTE, nfccHost_);
220 nfcWatchDog.Run();
221
222 bool result = nfccHost_->Deinitialize();
223 InfoLog("NfccHost deinitialize result %{public}d", result);
224
225 nfcWatchDog.Cancel();
226
227 {
228 std::lock_guard<std::mutex> lock(mutex_);
229 currPollingParams_ = NfcPollingParams::GetNfcOffParameters();
230 }
231
232 if (foregroundData_.isEnable_) {
233 DisableForegroundDispatch(foregroundData_.element_);
234 }
235
236 UpdateNfcState(KITS::STATE_OFF);
237 return result;
238 }
239
DoInitialize()240 void NfcService::DoInitialize()
241 {
242 // delay 5s to wait for bundle manager ready when device reboot
243 sleep(5);
244 eventHandler_->Intialize(tagDispatcher_, ceService_);
245 AppDataParser::GetInstance().InitAppList();
246
247 DebugLog("DoInitialize start FactoryReset");
248 nfccHost_->FactoryReset();
249
250 int lastState = NfcPrefImpl::GetInstance().GetInt(PREF_KEY_STATE);
251 if (lastState == KITS::STATE_ON) {
252 DoTurnOn();
253 }
254 }
255
SetRegisterCallBack(const sptr<INfcControllerCallback> & callback,const std::string & type,Security::AccessToken::AccessTokenID callerToken)256 int NfcService::SetRegisterCallBack(const sptr<INfcControllerCallback> &callback,
257 const std::string& type, Security::AccessToken::AccessTokenID callerToken)
258 {
259 InfoLog("NfcService SetRegisterCallBack");
260 std::lock_guard<std::mutex> lock(mutex_);
261 bool isExist = false;
262 NfcStateRegistryRecord record;
263 InfoLog("RecordsSize=%{public}zu,isExist=%{public}d,type=%{public}s,callerToken=%{public}d",
264 stateRecords_.size(), isExist, type.c_str(), callerToken);
265 for (size_t i = 0; i < stateRecords_.size(); i++) {
266 record = stateRecords_[i];
267 InfoLog("record.type_=%{public}s,record.callerToken=%{public}d",
268 record.type_.c_str(), record.callerToken_);
269 if (record.type_.compare(type) == 0 && record.callerToken_ == callerToken) {
270 isExist = true;
271 break;
272 }
273 }
274 InfoLog("isExist=%{public}d", isExist);
275 if (!isExist) {
276 record.type_ = type;
277 record.callerToken_ = callerToken;
278 record.nfcStateChangeCallback_ = callback;
279 stateRecords_.push_back(record);
280 }
281 return KITS::ERR_NONE;
282 }
283
RemoveRegisterCallBack(const std::string & type,Security::AccessToken::AccessTokenID callerToken)284 int NfcService::RemoveRegisterCallBack(const std::string& type,
285 Security::AccessToken::AccessTokenID callerToken)
286 {
287 InfoLog("NfcService RemoveRegisterCallBack");
288 std::lock_guard<std::mutex> lock(mutex_);
289 int32_t result = KITS::ERR_NFC_PARAMETERS;
290 std::vector<NfcStateRegistryRecord>::iterator it;
291 for (it = stateRecords_.begin(); it != stateRecords_.end(); ++it) {
292 if (it->type_.compare(type) == 0 && it->callerToken_ == callerToken) {
293 InfoLog("NfcService RemoveRegisterCallBack success.");
294 stateRecords_.erase(it);
295 result = KITS::ERR_NONE;
296 break;
297 }
298 }
299 return result;
300 }
301
RemoveAllRegisterCallBack(Security::AccessToken::AccessTokenID callerToken)302 int NfcService::RemoveAllRegisterCallBack(Security::AccessToken::AccessTokenID callerToken)
303 {
304 InfoLog("NfcService RemoveAllRegisterCallBack");
305 std::lock_guard<std::mutex> lock(mutex_);
306 int32_t result = KITS::ERR_NFC_PARAMETERS;
307 std::vector<NfcStateRegistryRecord>::iterator it;
308 for (it = stateRecords_.begin(); it != stateRecords_.end(); ++it) {
309 if (it->callerToken_ == callerToken) {
310 InfoLog("NfcService RemoveAllRegisterCallBack success.");
311 stateRecords_.erase(it);
312 result = KITS::ERR_NONE;
313 break;
314 }
315 }
316 return result;
317 }
318
UpdateNfcState(int newState)319 void NfcService::UpdateNfcState(int newState)
320 {
321 DebugLog("Update nfc state: oldState %{public}d, newState %{public}d", nfcState_, newState);
322 {
323 std::lock_guard<std::mutex> lock(mutex_);
324 if (newState == nfcState_) {
325 return;
326 }
327 nfcState_ = newState;
328 }
329 NfcPrefImpl::GetInstance().SetInt(PREF_KEY_STATE, newState);
330
331 // noitfy the common event for nfc state changed.
332 AAFwk::Want want;
333 want.SetAction(KITS::COMMON_EVENT_NFC_ACTION_STATE_CHANGED);
334 want.SetParam(KITS::NFC_EXTRA_STATE, newState);
335 EventFwk::CommonEventData data;
336 data.SetWant(want);
337 EventFwk::CommonEventManager::PublishCommonEvent(data);
338
339 // notify the nfc state changed by callback to JS APP
340 std::lock_guard<std::mutex> lock(mutex_);
341 DebugLog("stateRecords_.size[%{public}zu]", stateRecords_.size());
342 for (size_t i = 0; i < stateRecords_.size(); i++) {
343 NfcStateRegistryRecord record = stateRecords_[i];
344 DebugLog("stateRecords_[%{public}d]:type_=%{public}s,callerToken=%{public}d",
345 (int)i, record.type_.c_str(), record.callerToken_);
346 if (record.nfcStateChangeCallback_ != nullptr) {
347 InfoLog("UpdateNfcState, OnNfcStateChanged = %{public}d", newState);
348 record.nfcStateChangeCallback_->OnNfcStateChanged(newState);
349 }
350 }
351 }
352
StartPollingLoop(bool force)353 void NfcService::StartPollingLoop(bool force)
354 {
355 InfoLog("StartPollingLoop force = %{public}d", force);
356 if (!IsNfcEnabled()) {
357 return;
358 }
359 std::lock_guard<std::mutex> lock(mutex_);
360
361 NfcWatchDog pollingWatchDog("StartPollingLoop", WAIT_MS_SET_ROUTE, nfccHost_);
362 pollingWatchDog.Run();
363 // Compute new polling parameters
364 std::shared_ptr<NfcPollingParams> newParams = GetPollingParameters(screenState_);
365 InfoLog("newParams: %{public}s", newParams->ToString().c_str());
366 InfoLog("currParams: %{public}s", currPollingParams_->ToString().c_str());
367 if (force || !(newParams == currPollingParams_)) {
368 if (newParams->ShouldEnablePolling()) {
369 bool shouldRestart = currPollingParams_->ShouldEnablePolling();
370 InfoLog("StartPollingLoop shouldRestart = %{public}d", shouldRestart);
371
372 nfccHost_->EnableDiscovery(newParams->GetTechMask(),
373 newParams->ShouldEnableReaderMode(),
374 newParams->ShouldEnableHostRouting(),
375 shouldRestart || force);
376 } else {
377 nfccHost_->DisableDiscovery();
378 }
379 currPollingParams_ = newParams;
380 } else {
381 InfoLog("StartPollingLoop: polling params equal, not updating");
382 }
383 pollingWatchDog.Cancel();
384 }
385
GetPollingParameters(int screenState)386 std::shared_ptr<NfcPollingParams> NfcService::GetPollingParameters(int screenState)
387 {
388 // Recompute polling parameters based on screen state
389 std::shared_ptr<NfcPollingParams> params = std::make_shared<NfcPollingParams>();
390
391 if (foregroundData_.isEnable_) {
392 params->SetTechMask(foregroundData_.techMask_);
393 params->SetEnableReaderMode(true);
394 } else {
395 params->SetTechMask(NfcPollingParams::NFC_POLL_DEFAULT);
396 params->SetEnableReaderMode(false);
397 }
398 return params;
399 }
400
GetNfcState()401 int NfcService::GetNfcState()
402 {
403 std::lock_guard<std::mutex> lock(mutex_);
404 return nfcState_;
405 }
406
GetScreenState()407 int NfcService::GetScreenState()
408 {
409 std::lock_guard<std::mutex> lock(mutex_);
410 return screenState_;
411 }
412
GetNciVersion()413 int NfcService::GetNciVersion()
414 {
415 return nciVersion_;
416 }
417
IsNfcEnabled()418 bool NfcService::IsNfcEnabled()
419 {
420 std::lock_guard<std::mutex> lock(mutex_);
421 DebugLog("IsNfcEnabled, nfcState_=%{public}d", nfcState_);
422 return (nfcState_ == KITS::STATE_ON);
423 }
424
HandleScreenChanged(int screenState)425 void NfcService::HandleScreenChanged(int screenState)
426 {
427 std::lock_guard<std::mutex> lock(mutex_);
428 screenState_ = screenState;
429 DebugLog("Screen changed screenState %{public}d", screenState_);
430 nfccHost_->SetScreenStatus(screenState_);
431 }
432
HandlePackageUpdated(std::shared_ptr<EventFwk::CommonEventData> data)433 void NfcService::HandlePackageUpdated(std::shared_ptr<EventFwk::CommonEventData> data)
434 {
435 std::lock_guard<std::mutex> lock(mutex_);
436 std::string action = data->GetWant().GetAction();
437 if (action.empty()) {
438 ErrorLog("action is empty");
439 return;
440 }
441 if ((action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED) ||
442 (action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED)) {
443 AppDataParser::GetInstance().HandleAppAddOrChangedEvent(data);
444 } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED) {
445 AppDataParser::GetInstance().HandleAppRemovedEvent(data);
446 } else {
447 DebugLog("not need event.");
448 }
449 }
450
CommitRouting()451 void NfcService::CommitRouting()
452 {
453 eventHandler_->SendEvent(static_cast<uint32_t>(NfcCommonEvent::MSG_COMMIT_ROUTING), ROUTING_DELAY_TIME);
454 }
455
HandleCommitRouting()456 void NfcService::HandleCommitRouting()
457 {
458 std::lock_guard<std::mutex> lock(mutex_);
459 if (nfcState_ == KITS::STATE_OFF || nfcState_ == KITS::STATE_TURNING_OFF) {
460 DebugLog("NOT Handle CommitRouting in state off or turning off.");
461 return;
462 }
463 if (currPollingParams_->ShouldEnablePolling()) {
464 bool result = nfccHost_->CommitRouting();
465 DebugLog("HandleCommitRouting result = %{public}d", result);
466 } else {
467 DebugLog("NOT Handle CommitRouting when polling not enabled.");
468 }
469 }
470
ComputeRoutingParams()471 void NfcService::ComputeRoutingParams()
472 {
473 eventHandler_->SendEvent(static_cast<uint32_t>(NfcCommonEvent::MSG_COMPUTE_ROUTING_PARAMS), ROUTING_DELAY_TIME);
474 }
475
HandleComputeRoutingParams()476 void NfcService::HandleComputeRoutingParams()
477 {
478 if (!IsNfcEnabled()) {
479 ErrorLog("HandleComputeRoutingParams: NFC not enabled, do not Compute Routing Params");
480 return;
481 }
482 std::lock_guard<std::mutex> lock(mutex_);
483 bool result = nfccHost_->ComputeRoutingParams();
484 DebugLog("HandleComputeRoutingParams result = %{public}d", result);
485 }
486
GetTechMaskFromTechList(std::vector<uint32_t> & discTech)487 uint16_t NfcService::GetTechMaskFromTechList(std::vector<uint32_t> &discTech)
488 {
489 uint16_t techMask = 0;
490 for (uint16_t i = 0; i < sizeof(discTech); i++) {
491 switch (discTech[i]) {
492 case static_cast<int32_t>(KITS::TagTechnology::NFC_A_TECH):
493 techMask |= NFA_TECHNOLOGY_MASK_A;
494 break;
495 case static_cast<int32_t>(KITS::TagTechnology::NFC_B_TECH):
496 techMask |= NFA_TECHNOLOGY_MASK_B;
497 break;
498 case static_cast<int32_t>(KITS::TagTechnology::NFC_F_TECH):
499 techMask |= NFA_TECHNOLOGY_MASK_F;
500 break;
501 case static_cast<int32_t>(KITS::TagTechnology::NFC_V_TECH):
502 techMask |= NFA_TECHNOLOGY_MASK_V;
503 break;
504 default:
505 break;
506 }
507 }
508 return techMask;
509 }
510
EnableForegroundDispatch(AppExecFwk::ElementName element,std::vector<uint32_t> & discTech,const sptr<KITS::IForegroundCallback> & callback)511 bool NfcService::EnableForegroundDispatch(AppExecFwk::ElementName element, std::vector<uint32_t> &discTech,
512 const sptr<KITS::IForegroundCallback> &callback)
513 {
514 if (!IsNfcEnabled()) {
515 ErrorLog("EnableForegroundDispatch: NFC not enabled, do not set foreground");
516 return false;
517 }
518 bool isDisablePolling = (discTech.size() == 0);
519 DebugLog("EnableForegroundDispatch: element: %{public}s/%{public}s",
520 element.GetBundleName().c_str(), element.GetAbilityName().c_str());
521 if (!isDisablePolling) {
522 foregroundData_.isEnable_ = true;
523 foregroundData_.techMask_ = GetTechMaskFromTechList(discTech);
524 foregroundData_.element_ = element;
525 foregroundData_.callback_ = callback;
526 }
527 StartPollingLoop(true);
528 return true;
529 }
530
DisableForegroundDispatch(AppExecFwk::ElementName element)531 bool NfcService::DisableForegroundDispatch(AppExecFwk::ElementName element)
532 {
533 DebugLog("DisableForegroundDispatch: element: %{public}s/%{public}s",
534 element.GetBundleName().c_str(), element.GetAbilityName().c_str());
535 foregroundData_.isEnable_ = false;
536 foregroundData_.techMask_ = 0xFFFF;
537 foregroundData_.callerToken_ = 0;
538 foregroundData_.callback_ = nullptr;
539
540 StartPollingLoop(true);
541 return true;
542 }
543
DisableForegroundByDeathRcpt()544 bool NfcService::DisableForegroundByDeathRcpt()
545 {
546 return DisableForegroundDispatch(foregroundData_.element_);
547 }
548
IsForegroundEnabled()549 bool NfcService::IsForegroundEnabled()
550 {
551 return foregroundData_.isEnable_;
552 }
553
SendTagToForeground(KITS::TagInfoParcelable tagInfo)554 void NfcService::SendTagToForeground(KITS::TagInfoParcelable tagInfo)
555 {
556 if (!IsForegroundEnabled() || foregroundData_.callback_ == nullptr) {
557 ErrorLog("SendTagToForeground: invalid foreground state");
558 return;
559 }
560 DebugLog("SendTagToForeground: OnTagDiscovered, tagInfo = %{public}s", tagInfo.ToString().c_str());
561 foregroundData_.callback_->OnTagDiscovered(tagInfo);
562 }
563 } // namespace NFC
564 } // namespace OHOS
565