• 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 
NfcService(std::unique_ptr<NFC::NCI::INfccHost> nfccHost)33 NfcService::NfcService(std::unique_ptr<NFC::NCI::INfccHost> nfccHost)
34     : nfccHost_(std::move(nfccHost)),
35     nfcControllerImpl_(nullptr),
36     eventHandler_(nullptr),
37     tagDispatcher_(nullptr),
38     nfcState_(KITS::STATE_OFF)
39 {
40 }
41 
~NfcService()42 NfcService::~NfcService()
43 {
44     nfcControllerImpl_ = nullptr;
45     if (task_ && task_->joinable()) {
46         task_->join();
47     }
48     if (rootTask_ && rootTask_->joinable()) {
49         rootTask_->join();
50     }
51 }
52 
GetInstance() const53 std::weak_ptr<NfcService> NfcService::GetInstance() const
54 {
55     return nfcService_;
56 }
57 
Initialize()58 bool NfcService::Initialize()
59 {
60     nfcService_ = shared_from_this();
61     InfoLog("Nfc service initialize.");
62     if (nfccHost_) {
63         nfccHost_->SetNfccHostListener(nfcService_);
64     } else {
65         nfccHost_ = std::make_shared<NFC::NCI::NfccHost>(nfcService_);
66     }
67 
68     // inner message handler, used by other modules as initialization parameters
69     std::shared_ptr<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create("nfcservice::EventRunner");
70     eventHandler_ = std::make_shared<CommonEventHandler>(runner, shared_from_this());
71     tagDispatcher_ = std::make_shared<TAG::TagDispatcher>(shared_from_this());
72     tagSessionIface_ = new TAG::TagSession(shared_from_this());
73 
74     // To be structured after Tag and HCE, the controller module is the controller of tag and HCE module
75     nfcControllerImpl_ = new NfcControllerImpl(shared_from_this());
76 
77     currPollingParams_ = NfcPollingParams::GetNfcOffParameters();
78 
79     runner->Run();
80     // NFC ROOT
81     ExecuteTask(KITS::TASK_INITIALIZE);
82     return true;
83 }
84 
GetTagDispatcher()85 std::weak_ptr<TAG::TagDispatcher> NfcService::GetTagDispatcher()
86 {
87     return tagDispatcher_;
88 }
89 
GetTagServiceIface()90 OHOS::sptr<IRemoteObject> NfcService::GetTagServiceIface()
91 {
92     return tagSessionIface_;
93 }
94 
OnTagDiscovered(std::shared_ptr<NCI::ITagHost> tagHost)95 void NfcService::OnTagDiscovered(std::shared_ptr<NCI::ITagHost> tagHost)
96 {
97     InfoLog("NfcService::OnTagDiscovered");
98     eventHandler_->SendEvent<NCI::ITagHost>(static_cast<uint32_t>(NfcCommonEvent::MSG_TAG_FOUND), tagHost);
99 }
100 
IsNfcTaskReady(std::future<int> & future) const101 bool NfcService::IsNfcTaskReady(std::future<int>& future) const
102 {
103     if (future.valid()) {
104         if (std::future_status::ready != future.wait_for(std::chrono::seconds(1))) {
105             return false;
106         }
107     }
108     return true;
109 }
110 
ExecuteTask(KITS::NfcTask param)111 void NfcService::ExecuteTask(KITS::NfcTask param)
112 {
113     std::lock_guard<std::mutex> lock(mutex_);
114     if (nfcState_ == KITS::STATE_TURNING_OFF || nfcState_ == KITS::STATE_TURNING_ON) {
115         WarnLog("Execute task %{public}d from bad state %{public}d", param, nfcState_);
116         return;
117     }
118 
119     // Check the current state
120     if (param == KITS::TASK_TURN_ON && nfcState_ == KITS::STATE_ON) {
121         WarnLog("NFC Turn On, already On");
122         return;
123     }
124     if (param == KITS::TASK_TURN_OFF && nfcState_ == KITS::STATE_OFF) {
125         WarnLog("NFC Turn Off, already Off");
126         return;
127     }
128 
129     std::promise<int> promise;
130     if (rootTask_) {
131         if (!IsNfcTaskReady(future_)) {
132             WarnLog("ExecuteTask, IsNfcTaskReady is false.");
133             return;
134         }
135         if (task_ && task_->joinable()) {
136             task_->join();
137         }
138         future_ = promise.get_future();
139         task_ = std::make_unique<std::thread>(&NfcService::NfcTaskThread, this, param, std::move(promise));
140     } else {
141         rootTask_ = std::make_unique<std::thread>(&NfcService::NfcTaskThread, this, param, std::move(promise));
142     }
143 }
144 
NfcTaskThread(KITS::NfcTask params,std::promise<int> promise)145 void NfcService::NfcTaskThread(KITS::NfcTask params, std::promise<int> promise)
146 {
147     InfoLog("Nfc task thread params %{public}d", params);
148     switch (params) {
149         case KITS::TASK_TURN_ON:
150             DoTurnOn();
151             break;
152         case KITS::TASK_TURN_OFF:
153             DoTurnOff();
154             break;
155         case KITS::TASK_INITIALIZE:
156             DoInitialize();
157             break;
158         case KITS::TASK_START_POLLING_LOOP:
159             StartPollingLoop(false);
160             break;
161         default:
162             break;
163     }
164     promise.set_value_at_thread_exit(0);
165     return;
166 }
167 
DoTurnOn()168 bool NfcService::DoTurnOn()
169 {
170     InfoLog("Nfc do turn on: current state %{public}d", nfcState_);
171     UpdateNfcState(KITS::STATE_TURNING_ON);
172 
173     NfcWatchDog nfcWatchDog("DoTurnOn", WAIT_MS_INIT, nfccHost_);
174     nfcWatchDog.Run();
175     // Routing WakeLock acquire
176     if (!nfccHost_->Initialize()) {
177         ErrorLog("Nfc do turn on err");
178         UpdateNfcState(KITS::STATE_OFF);
179         // Routing Wake Lock release
180         nfcWatchDog.Cancel();
181         return false;
182     }
183     // Routing Wake Lock release
184     nfcWatchDog.Cancel();
185 
186     nciVersion_ = nfccHost_->GetNciVersion();
187     InfoLog("Get nci version: ver %{public}d", nciVersion_);
188 
189     UpdateNfcState(KITS::STATE_ON);
190 
191     nfccHost_->SetScreenStatus(screenState_);
192 
193     /* Start polling loop */
194     StartPollingLoop(true);
195 
196     return true;
197 }
198 
DoTurnOff()199 bool NfcService::DoTurnOff()
200 {
201     InfoLog("Nfc do turn off: current state %{public}d", nfcState_);
202     UpdateNfcState(KITS::STATE_TURNING_OFF);
203 
204     /* WatchDog to monitor for Deinitialize failed */
205     NfcWatchDog nfcWatchDog("DoTurnOff", WAIT_MS_SET_ROUTE, nfccHost_);
206     nfcWatchDog.Run();
207 
208     bool result = nfccHost_->Deinitialize();
209     InfoLog("NfccHost deinitialize result %{public}d", result);
210 
211     nfcWatchDog.Cancel();
212 
213     {
214         std::lock_guard<std::mutex> lock(mutex_);
215         currPollingParams_ = NfcPollingParams::GetNfcOffParameters();
216     }
217 
218     UpdateNfcState(KITS::STATE_OFF);
219     return result;
220 }
221 
DoInitialize()222 void NfcService::DoInitialize()
223 {
224     // delay 5s to wait for bundle manager ready when device reboot
225     sleep(5);
226     eventHandler_->Intialize(tagDispatcher_);
227     AppDataParser::GetInstance().InitAppList();
228 
229     DebugLog("DoInitialize start FactoryReset");
230     nfccHost_->FactoryReset();
231 
232     int lastState = NfcPrefImpl::GetInstance().GetInt(PREF_KEY_STATE);
233     if (lastState == KITS::STATE_ON) {
234         DoTurnOn();
235     }
236 }
237 
SetRegisterCallBack(const sptr<INfcControllerCallback> & callback,const std::string & type,Security::AccessToken::AccessTokenID callerToken)238 int NfcService::SetRegisterCallBack(const sptr<INfcControllerCallback> &callback,
239     const std::string& type, Security::AccessToken::AccessTokenID callerToken)
240 {
241     InfoLog("NfcService SetRegisterCallBack");
242     std::lock_guard<std::mutex> lock(mutex_);
243     bool isExist = false;
244     NfcStateRegistryRecord record;
245     InfoLog("RecordsSize=%{public}zu,isExist=%{public}d,type=%{public}s,callerToken=%{public}d",
246         stateRecords_.size(), isExist, type.c_str(), callerToken);
247     for (size_t i = 0; i < stateRecords_.size(); i++) {
248         record = stateRecords_[i];
249         InfoLog("record.type_=%{public}s,record.callerToken=%{public}d",
250             record.type_.c_str(), record.callerToken_);
251         if (record.type_.compare(type) == 0 && record.callerToken_ == callerToken) {
252             isExist = true;
253             break;
254         }
255     }
256     InfoLog("isExist=%{public}d", isExist);
257     if (!isExist) {
258         record.type_ = type;
259         record.callerToken_ = callerToken;
260         record.nfcStateChangeCallback_ = callback;
261         stateRecords_.push_back(record);
262     }
263     return KITS::ERR_NONE;
264 }
265 
RemoveRegisterCallBack(const std::string & type,Security::AccessToken::AccessTokenID callerToken)266 int NfcService::RemoveRegisterCallBack(const std::string& type,
267     Security::AccessToken::AccessTokenID callerToken)
268 {
269     InfoLog("NfcService RemoveRegisterCallBack");
270     std::lock_guard<std::mutex> lock(mutex_);
271     int32_t result = KITS::ERR_NFC_PARAMETERS;
272     std::vector<NfcStateRegistryRecord>::iterator it;
273     for (it = stateRecords_.begin(); it != stateRecords_.end(); ++it) {
274         if (it->type_.compare(type) == 0 && it->callerToken_ == callerToken) {
275             InfoLog("NfcService RemoveRegisterCallBack success.");
276             stateRecords_.erase(it);
277             result = KITS::ERR_NONE;
278             break;
279         }
280     }
281     return result;
282 }
283 
RemoveAllRegisterCallBack(Security::AccessToken::AccessTokenID callerToken)284 int NfcService::RemoveAllRegisterCallBack(Security::AccessToken::AccessTokenID callerToken)
285 {
286     InfoLog("NfcService RemoveAllRegisterCallBack");
287     std::lock_guard<std::mutex> lock(mutex_);
288     int32_t result = KITS::ERR_NFC_PARAMETERS;
289     std::vector<NfcStateRegistryRecord>::iterator it;
290     for (it = stateRecords_.begin(); it != stateRecords_.end(); ++it) {
291         if (it->callerToken_ == callerToken) {
292             InfoLog("NfcService RemoveAllRegisterCallBack success.");
293             stateRecords_.erase(it);
294             result = KITS::ERR_NONE;
295             break;
296         }
297     }
298     return result;
299 }
300 
UpdateNfcState(int newState)301 void NfcService::UpdateNfcState(int newState)
302 {
303     DebugLog("Update nfc state: oldState %{public}d, newState %{public}d", nfcState_, newState);
304     {
305         std::lock_guard<std::mutex> lock(mutex_);
306         if (newState == nfcState_) {
307             return;
308         }
309         nfcState_ = newState;
310     }
311     NfcPrefImpl::GetInstance().SetInt(PREF_KEY_STATE, newState);
312 
313     // noitfy the common event for nfc state changed.
314     AAFwk::Want want;
315     want.SetAction(KITS::COMMON_EVENT_NFC_ACTION_STATE_CHANGED);
316     want.SetParam(KITS::NFC_EXTRA_STATE, newState);
317     EventFwk::CommonEventData data;
318     data.SetWant(want);
319     EventFwk::CommonEventManager::PublishCommonEvent(data);
320 
321     // notify the nfc state changed by callback to JS APP
322     std::lock_guard<std::mutex> lock(mutex_);
323     DebugLog("stateRecords_.size[%{public}zu]", stateRecords_.size());
324     for (size_t i = 0; i < stateRecords_.size(); i++) {
325         NfcStateRegistryRecord record = stateRecords_[i];
326         DebugLog("stateRecords_[%{public}d]:type_=%{public}s,callerToken=%{public}d",
327             (int)i, record.type_.c_str(), record.callerToken_);
328         if (record.nfcStateChangeCallback_ != nullptr) {
329             InfoLog("UpdateNfcState, OnNfcStateChanged = %{public}d", newState);
330             record.nfcStateChangeCallback_->OnNfcStateChanged(newState);
331         }
332     }
333 }
334 
ExecuteStartPollingLoop()335 void NfcService::ExecuteStartPollingLoop()
336 {
337     ExecuteTask(KITS::TASK_START_POLLING_LOOP);
338 }
339 
StartPollingLoop(bool force)340 void NfcService::StartPollingLoop(bool force)
341 {
342     InfoLog("StartPollingLoop force = %{public}d", force);
343     if (!IsNfcEnabled()) {
344         return;
345     }
346     std::lock_guard<std::mutex> lock(mutex_);
347 
348     NfcWatchDog pollingWatchDog("StartPollingLoop", WAIT_MS_SET_ROUTE, nfccHost_);
349     pollingWatchDog.Run();
350     // Compute new polling parameters
351     std::shared_ptr<NfcPollingParams> newParams = GetPollingParameters(screenState_);
352     InfoLog("newParams: %{public}s", newParams->ToString().c_str());
353     InfoLog("currParams: %{public}s", currPollingParams_->ToString().c_str());
354     if (force || !(newParams == currPollingParams_)) {
355         if (newParams->ShouldEnablePolling()) {
356             bool shouldRestart = currPollingParams_->ShouldEnablePolling();
357             InfoLog("StartPollingLoop shouldRestart = %{public}d", shouldRestart);
358 
359             nfccHost_->EnableDiscovery(newParams->GetTechMask(),
360                                        newParams->ShouldEnableReaderMode(),
361                                        newParams->ShouldEnableHostRouting(),
362                                        shouldRestart || force);
363         } else {
364             nfccHost_->DisableDiscovery();
365         }
366         currPollingParams_ = newParams;
367     } else {
368         InfoLog("StartPollingLoop: polling params equal, not updating");
369     }
370     pollingWatchDog.Cancel();
371 }
372 
GetPollingParameters(int screenState)373 std::shared_ptr<NfcPollingParams> NfcService::GetPollingParameters(int screenState)
374 {
375     // Recompute polling parameters based on screen state
376     std::shared_ptr<NfcPollingParams> params = std::make_shared<NfcPollingParams>();
377 
378     params->SetTechMask(NfcPollingParams::NFC_POLL_DEFAULT);
379     return params;
380 }
381 
GetNfcState()382 int NfcService::GetNfcState()
383 {
384     std::lock_guard<std::mutex> lock(mutex_);
385     return nfcState_;
386 }
387 
GetScreenState()388 int NfcService::GetScreenState()
389 {
390     std::lock_guard<std::mutex> lock(mutex_);
391     return screenState_;
392 }
393 
GetNciVersion()394 int NfcService::GetNciVersion()
395 {
396     return nciVersion_;
397 }
398 
IsNfcEnabled()399 bool NfcService::IsNfcEnabled()
400 {
401     std::lock_guard<std::mutex> lock(mutex_);
402     DebugLog("IsNfcEnabled, nfcState_=%{public}d", nfcState_);
403     return (nfcState_ == KITS::STATE_ON);
404 }
405 
HandleScreenChanged(int screenState)406 void NfcService::HandleScreenChanged(int screenState)
407 {
408     std::lock_guard<std::mutex> lock(mutex_);
409     screenState_ = screenState;
410     DebugLog("Screen changed screenState %{public}d", screenState_);
411     nfccHost_->SetScreenStatus(screenState_);
412 }
413 
HandlePackageUpdated(std::shared_ptr<EventFwk::CommonEventData> data)414 void NfcService::HandlePackageUpdated(std::shared_ptr<EventFwk::CommonEventData> data)
415 {
416     std::lock_guard<std::mutex> lock(mutex_);
417     std::string action = data->GetWant().GetAction();
418     if (action.empty()) {
419         ErrorLog("action is empty");
420         return;
421     }
422     if ((action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED) ||
423         (action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED)) {
424         AppDataParser::GetInstance().HandleAppAddOrChangedEvent(data);
425     } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED) {
426         AppDataParser::GetInstance().HandleAppRemovedEvent(data);
427     } else {
428         DebugLog("not need event.");
429     }
430 }
431 }  // namespace NFC
432 }  // namespace OHOS
433