1 /*
2  * Copyright (C) 2024 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 
16 #include "nfc_notification_publisher.h"
17 
18 #include <dlfcn.h>
19 
20 #include "loghelper.h"
21 
22 namespace OHOS {
23 namespace NFC {
24 namespace TAG {
GetInstance()25 NfcNotificationPublisher& NfcNotificationPublisher::GetInstance()
26 {
27     static NfcNotificationPublisher instance;
28     return instance;
29 }
30 
NfcNotificationPublisher()31 NfcNotificationPublisher::NfcNotificationPublisher()
32 {
33     InfoLog("NfcNotificationPublisher constructor enter.");
34     if (!isNtfLibLoaded_) {
35         InitNfcNtfLib();
36     }
37 }
38 
~NfcNotificationPublisher()39 NfcNotificationPublisher::~NfcNotificationPublisher()
40 {
41     InfoLog("NfcNotificationPublisher destructor enter.");
42     UnloadNfcNtfLib();
43 }
44 
NfcNotificationCallback(int notificationId)45 static void NfcNotificationCallback(int notificationId)
46 {
47     NfcNotificationPublisher::GetInstance().OnNotificationButtonClicked(notificationId);
48 }
49 
PublishNfcNotification(int notificationId,const std::string & name,int balance)50 void NfcNotificationPublisher::PublishNfcNotification(int notificationId, const std::string &name, int balance)
51 {
52     if (nfcNtfInf_.publishNotification == nullptr) {
53         ErrorLog("func handle nullptr, fail to publish notification");
54         return;
55     }
56     if (notificationId == NFC_NO_HAP_SUPPORTED_NOTIFICATION_ID) {
57         usleep(NOTIFICATION_WAIT_TIME_US);
58     }
59     nfcNtfInf_.publishNotification(notificationId, name, balance);
60 }
61 
RegNotificationCallback(std::weak_ptr<NfcService> service)62 void NfcNotificationPublisher::RegNotificationCallback(std::weak_ptr<NfcService> service)
63 {
64     std::lock_guard<std::mutex> lock(mutex_);
65     if (!isInitialized_ || nfcService_.expired()) {
66         nfcService_ = service;
67         isInitialized_ = true;
68     }
69     if (nfcNtfInf_.regNtfCallback == nullptr) {
70         ErrorLog("func handle nullptr, fail to publish notification");
71         return;
72     }
73     nfcNtfInf_.regNtfCallback(NfcNotificationCallback);
74 }
75 
UnloadNfcNtfLib()76 void NfcNotificationPublisher::UnloadNfcNtfLib()
77 {
78     if (nfcNtfHandle_ != nullptr) {
79         dlclose(nfcNtfHandle_);
80         nfcNtfHandle_ = nullptr;
81     }
82 
83     isNtfLibLoaded_ = false;
84 }
85 
InitNfcNtfLib()86 void NfcNotificationPublisher::InitNfcNtfLib()
87 {
88     if (isNtfLibLoaded_) {
89         InfoLog("nfc notification lib already loaded.");
90         return;
91     }
92     nfcNtfHandle_ = dlopen(NFC_NTF_LIB_PATH, RTLD_LAZY | RTLD_GLOBAL);
93     if (nfcNtfHandle_ == nullptr) {
94         ErrorLog("fail to dlopen nfc notification lib.");
95         return;
96     }
97     nfcNtfInf_.regNtfCallback = reinterpret_cast<void (*)(NfcNtfCallback *)>
98         (dlsym(nfcNtfHandle_, REG_NFC_CALLBACK_FUNC_NAME));
99     nfcNtfInf_.publishNotification = reinterpret_cast<void (*)(int, const std::string &, int)>
100         (dlsym(nfcNtfHandle_, PUBLISH_NTF_FUNC_NAME));
101     if (nfcNtfInf_.regNtfCallback == nullptr || nfcNtfInf_.publishNotification == nullptr) {
102         ErrorLog("fail to dlsym nfc notification lib.");
103         UnloadNfcNtfLib();
104         return;
105     }
106     isNtfLibLoaded_ = true;
107 }
108 
OnNotificationButtonClicked(int notificationId)109 void NfcNotificationPublisher::OnNotificationButtonClicked(int notificationId)
110 {
111     std::lock_guard<std::mutex> lock(mutex_);
112     if (nfcService_.expired()) {
113         ErrorLog("nfc service expired, fail to callback.");
114         return;
115     }
116     std::weak_ptr<TAG::TagDispatcher> tagDispatcher = nfcService_.lock()->GetTagDispatcher();
117     if (tagDispatcher.expired()) {
118         ErrorLog("tagDispatcher expired, fail to inform button clicking");
119         return;
120     }
121     tagDispatcher.lock()->OnNotificationButtonClicked(notificationId);
122 }
123 }  // namespace TAG
124 }  // namespace NFC
125 }  // namespace OHOS