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_controller.h"
16
17#include "loghelper.h"
18#include "nfc_controller_callback_stub.h"
19#include "nfc_sa_client.h"
20#include "nfc_sdk_common.h"
21#include "indef_msg_callback.h"
22#include "infc_controller_callback.h"
23#include "iservice_registry.h"
24#include "system_ability_definition.h"
25#ifdef VENDOR_APPLICATIONS_ENABLED
26#include "on_card_emulation_notify_cb_stub.h"
27#include "query_app_info_callback_stub.h"
28#endif
29
30namespace OHOS {
31namespace NFC {
32namespace KITS {
33std::shared_ptr<OHOS::NFC::NfcControllerProxy> NfcController::nfcControllerProxy_;
34std::weak_ptr<INfcControllerService> NfcController::nfcControllerService_;
35sptr<IRemoteObject::DeathRecipient> NfcController::deathRecipient_;
36sptr<IRemoteObject> NfcController::remote_;
37bool NfcController::initialized_ = false;
38bool NfcController::remoteDied_ = true;
39std::mutex NfcController::mutex_;
40#ifdef VENDOR_APPLICATIONS_ENABLED
41static sptr<QueryAppInfoCallbackStub> g_queryAppInfoCallbackStub =
42    sptr<QueryAppInfoCallbackStub>(new (std::nothrow) QueryAppInfoCallbackStub());
43static sptr<OnCardEmulationNotifyCbStub> g_onCardEmulationNotifyCbStub =
44    sptr<OnCardEmulationNotifyCbStub>(new (std::nothrow) OnCardEmulationNotifyCbStub());
45#endif
46
47NfcController::NfcController()
48{
49    DebugLog("[NfcController::NfcController] new ability manager");
50    deathRecipient_ = new (std::nothrow) NfcServiceDeathRecipient(*this);
51}
52
53NfcController::~NfcController()
54{
55    DebugLog("destruct NfcController");
56}
57
58void NfcController::InitNfcRemoteSA()
59{
60    DebugLog("NfcController::%{public}s in, initialized_ = %{public}d, nfcControllerService_ = %{public}d",
61        __func__, initialized_, nfcControllerService_.expired());
62    std::lock_guard<std::mutex> guard(mutex_);
63    if (!initialized_ || nfcControllerService_.expired() || remoteDied_) {
64        remote_ = NfcSaClient::GetInstance().LoadNfcSa(NFC_MANAGER_SYS_ABILITY_ID);
65        if (remote_ == nullptr) {
66            ErrorLog("Nfc Controller Is Unexist.");
67            return;
68        }
69        if (deathRecipient_ == nullptr) {
70            WarnLog("deathRecipient_ is nullptr!");
71        }
72        remote_->AddDeathRecipient(deathRecipient_);
73        InfoLog("%{public}s:add remote death listener", __func__);
74        nfcControllerProxy_ = std::make_shared<NfcControllerProxy>(remote_);
75        nfcControllerService_ = nfcControllerProxy_;
76
77        initialized_ = true;
78        remoteDied_ = false;
79    }
80    DebugLog("NfcController::%{public}s success.", __func__);
81}
82
83NfcController &NfcController::GetInstance()
84{
85    DebugLog("NfcController::GetInstance in.");
86    static NfcController instance;
87    return instance;
88}
89
90void NfcController::OnRemoteDied(const wptr<IRemoteObject> &remoteObject)
91{
92    WarnLog("%{public}s:Remote service is died!", __func__);
93    std::lock_guard<std::mutex> lock(mutex_);
94    remoteDied_ = true;
95    initialized_ = false;
96    if (deathRecipient_ == nullptr || remoteObject == nullptr) {
97        ErrorLog("deathRecipient_ is nullptr!");
98        return;
99    }
100    if (remote_ == nullptr) {
101        ErrorLog("remote_ is nullptr!");
102        return;
103    }
104    remote_->RemoveDeathRecipient(deathRecipient_);
105
106    nfcControllerService_.reset();
107    nfcControllerProxy_ = nullptr;
108    remote_ = nullptr;
109}
110
111// Open NFC
112int NfcController::TurnOn()
113{
114    InitNfcRemoteSA();
115    if (nfcControllerService_.expired()) {
116        return ErrorCode::ERR_NFC_STATE_UNBIND;
117    }
118    return nfcControllerService_.lock()->TurnOn();
119}
120
121// Close NFC
122int NfcController::TurnOff()
123{
124    InitNfcRemoteSA();
125    if (nfcControllerService_.expired()) {
126        return ErrorCode::ERR_NFC_STATE_UNBIND;
127    }
128    return nfcControllerService_.lock()->TurnOff();
129}
130
131// get NFC state
132int NfcController::GetNfcState()
133{
134    int state = NfcState::STATE_OFF;
135    if (!NfcSaClient::GetInstance().CheckNfcSystemAbility()) {
136        WarnLog("Nfc SA not started yet.");
137        return state;
138    }
139    InitNfcRemoteSA();
140    if (nfcControllerService_.expired()) {
141        ErrorLog("Nfc controller service expired.");
142        return state;
143    }
144    state = nfcControllerService_.lock()->GetState();
145    InfoLog("nfc state: %{public}d.", state);
146    return state;
147}
148
149// check whether NFC is supported
150bool NfcController::IsNfcAvailable()
151{
152    return true;
153}
154
155// check whether NFC is enabled
156int NfcController::IsNfcOpen(bool &isOpen)
157{
158    isOpen = (GetNfcState() == NfcState::STATE_ON);
159    return ErrorCode::ERR_NONE;
160}
161
162// register NFC state change callback
163ErrorCode NfcController::RegListener(const sptr<INfcControllerCallback> &callback,
164    const std::string& type)
165{
166    InfoLog("NfcController::RegListener");
167    if (!NfcSaClient::GetInstance().CheckNfcSystemAbility()) {
168        WarnLog("nfc SA not started yet.");
169        return ErrorCode::ERR_NFC_STATE_UNBIND;
170    }
171    InitNfcRemoteSA();
172    if (nfcControllerService_.expired()) {
173        ErrorLog("nfcControllerService_ expired.");
174        return ErrorCode::ERR_NFC_STATE_UNBIND;
175    }
176    return nfcControllerService_.lock()->RegisterCallBack(callback, type);
177}
178
179// unregister NFC state change
180ErrorCode NfcController::UnregListener(const std::string& type)
181{
182    InfoLog("NfcController::UnregListener");
183    if (!NfcSaClient::GetInstance().CheckNfcSystemAbility()) {
184        WarnLog("nfc SA not started yet.");
185        return ErrorCode::ERR_NFC_STATE_UNBIND;
186    }
187    InitNfcRemoteSA();
188    if (nfcControllerService_.expired()) {
189        ErrorLog("nfcControllerService_ expired.");
190        return ErrorCode::ERR_NFC_STATE_UNBIND;
191    }
192    return nfcControllerService_.lock()->UnRegisterCallBack(type);
193}
194
195OHOS::sptr<IRemoteObject> NfcController::GetTagServiceIface()
196{
197    InitNfcRemoteSA();
198    if (nfcControllerService_.expired()) {
199        ErrorLog("NfcController::GetTagServiceIface nfcControllerService_ expired");
200        return nullptr;
201    }
202    return nfcControllerService_.lock()->GetTagServiceIface();
203}
204
205ErrorCode NfcController::RegNdefMsgCb(const sptr<INdefMsgCallback> &callback)
206{
207    DebugLog("NfcController::RegNdefMsgCb");
208    InitNfcRemoteSA();
209    if (nfcControllerService_.expired()) {
210        ErrorLog("NfcController::RegNdefMsgCb nfcControllerService_ expired");
211        return ErrorCode::ERR_NFC_STATE_UNBIND;
212    }
213    return nfcControllerService_.lock()->RegNdefMsgCb(callback);
214}
215
216#ifdef VENDOR_APPLICATIONS_ENABLED
217ErrorCode NfcController::RegQueryApplicationCb(const std::string& type,
218    QueryApplicationByVendor tagCallback, QueryHceAppByVendor hceCallback)
219{
220    DebugLog("NfcController::RegQueryApplicationCb");
221    InitNfcRemoteSA();
222    if (nfcControllerService_.expired()) {
223        ErrorLog("NfcController::RegQueryApplicationCb nfcControllerService_ expired");
224        return ErrorCode::ERR_NFC_STATE_UNBIND;
225    }
226    if (type.compare(KEY_TAG_APP) == 0) {
227        g_queryAppInfoCallbackStub->RegisterQueryTagAppCallback(tagCallback);
228    } else if (type.compare(KEY_HCE_APP) == 0) {
229        g_queryAppInfoCallbackStub->RegisterQueryHceAppCallback(hceCallback);
230    }
231    return nfcControllerService_.lock()->RegQueryApplicationCb(g_queryAppInfoCallbackStub);
232}
233
234ErrorCode NfcController::RegCardEmulationNotifyCb(OnCardEmulationNotifyCb callback)
235{
236    DebugLog("NfcController::RegCardEmulationNotifyCb");
237    InitNfcRemoteSA();
238    if (nfcControllerService_.expired()) {
239        ErrorLog("NfcController::RegCardEmulationNotifyCb nfcControllerService_ expired");
240        return ErrorCode::ERR_NFC_STATE_UNBIND;
241    }
242    g_onCardEmulationNotifyCbStub->RegisterCallback(callback);
243    return nfcControllerService_.lock()->RegCardEmulationNotifyCb(g_onCardEmulationNotifyCbStub);
244}
245ErrorCode NfcController::NotifyEventStatus(int eventType, int arg1, std::string arg2)
246{
247    DebugLog("NfcController::NotifyEventStatus");
248    InitNfcRemoteSA();
249    if (nfcControllerService_.expired()) {
250        ErrorLog("NfcController::NotifyEventStatus nfcControllerService_ expired");
251        return ErrorCode::ERR_NFC_STATE_UNBIND;
252    }
253    return nfcControllerService_.lock()->NotifyEventStatus(eventType, arg1, arg2);
254}
255#endif
256
257OHOS::sptr<IRemoteObject> NfcController::GetHceServiceIface()
258{
259    InitNfcRemoteSA();
260    if (nfcControllerService_.expired()) {
261        ErrorLog("NfcController::GetHceServiceIface nfcControllerService_ expired");
262        return nullptr;
263    }
264    return nfcControllerService_.lock()->GetHceServiceIface();
265}
266}  // namespace KITS
267}  // namespace NFC
268}  // namespace OHOS