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