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