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