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 #include "nfc_data_share_impl.h"
22
23 namespace OHOS {
24 namespace NFC {
25 namespace TAG {
26 constexpr const char* NFC_NOT_DISTURB_KEYWORD = "settings.nfc.not_disturb";
27
GetInstance()28 NfcNotificationPublisher& NfcNotificationPublisher::GetInstance()
29 {
30 static NfcNotificationPublisher instance;
31 return instance;
32 }
33
NfcNotificationPublisher()34 NfcNotificationPublisher::NfcNotificationPublisher()
35 {
36 InfoLog("NfcNotificationPublisher constructor enter.");
37 if (!isNtfLibLoaded_) {
38 InitNfcNtfLib();
39 }
40 }
41
~NfcNotificationPublisher()42 NfcNotificationPublisher::~NfcNotificationPublisher()
43 {
44 InfoLog("NfcNotificationPublisher destructor enter.");
45 UnloadNfcNtfLib();
46 }
47
NfcNotificationCallback(int notificationId)48 static void NfcNotificationCallback(int notificationId)
49 {
50 NfcNotificationPublisher::GetInstance().OnNotificationButtonClicked(notificationId);
51 }
52
PublishNfcNotification(int notificationId,const std::string & name,int balance)53 void NfcNotificationPublisher::PublishNfcNotification(int notificationId, const std::string &name, int balance)
54 {
55 bool isNfcNotDisturb = IsNfcNtfDisabled();
56 if (nfcNtfInf_.publishNotification == nullptr) {
57 ErrorLog("func handle nullptr, fail to publish notification");
58 return;
59 }
60 if (notificationId == NFC_NO_HAP_SUPPORTED_NOTIFICATION_ID) {
61 usleep(NOTIFICATION_WAIT_TIME_US);
62 }
63 nfcNtfInf_.publishNotification(isNfcNotDisturb, notificationId, name, balance);
64 }
65
RegNotificationCallback(std::weak_ptr<NfcService> service)66 void NfcNotificationPublisher::RegNotificationCallback(std::weak_ptr<NfcService> service)
67 {
68 std::lock_guard<std::mutex> lock(mutex_);
69 if (!isInitialized_ || nfcService_.expired()) {
70 nfcService_ = service;
71 isInitialized_ = true;
72 }
73 if (nfcNtfInf_.regNtfCallback == nullptr) {
74 ErrorLog("func handle nullptr, fail to publish notification");
75 return;
76 }
77 nfcNtfInf_.regNtfCallback(NfcNotificationCallback);
78 }
79
UnloadNfcNtfLib()80 void NfcNotificationPublisher::UnloadNfcNtfLib()
81 {
82 if (nfcNtfHandle_ != nullptr) {
83 dlclose(nfcNtfHandle_);
84 nfcNtfHandle_ = nullptr;
85 }
86
87 isNtfLibLoaded_ = false;
88 }
89
InitNfcNtfLib()90 void NfcNotificationPublisher::InitNfcNtfLib()
91 {
92 if (isNtfLibLoaded_) {
93 InfoLog("nfc notification lib already loaded.");
94 return;
95 }
96 nfcNtfHandle_ = dlopen(NFC_NTF_LIB_PATH, RTLD_LAZY | RTLD_GLOBAL);
97 if (nfcNtfHandle_ == nullptr) {
98 ErrorLog("fail to dlopen nfc notification lib.");
99 return;
100 }
101 nfcNtfInf_.regNtfCallback = reinterpret_cast<void (*)(NfcNtfCallback *)>
102 (dlsym(nfcNtfHandle_, REG_NFC_CALLBACK_FUNC_NAME));
103 nfcNtfInf_.publishNotification = reinterpret_cast<void (*)(bool, int, const std::string &, int)>
104 (dlsym(nfcNtfHandle_, PUBLISH_NTF_FUNC_NAME));
105 if (nfcNtfInf_.regNtfCallback == nullptr || nfcNtfInf_.publishNotification == nullptr) {
106 ErrorLog("fail to dlsym nfc notification lib.");
107 UnloadNfcNtfLib();
108 return;
109 }
110 isNtfLibLoaded_ = true;
111 }
112
IsNfcNtfDisabled()113 bool NfcNotificationPublisher::IsNfcNtfDisabled()
114 {
115 const std::string NFC_NOT_DISTURB_SUFFIX =
116 "/com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true&key=settings.nfc.not_disturb";
117 const std::string NFC_NOT_DISTURB_PREFIX = "datashare://";
118 const std::string NFC_DATA_URI_NOT_DISTURB = NFC_NOT_DISTURB_PREFIX + NFC_NOT_DISTURB_SUFFIX;
119 Uri nfcNotDisturb(NFC_DATA_URI_NOT_DISTURB);
120
121 auto dataShare = NfcDataShareImpl::GetInstance();
122 if (dataShare == nullptr) {
123 ErrorLog("fail to get datashare.");
124 return false; // NFC not disturb switch is off by default.
125 }
126 int32_t value = INVALID_VALUE;
127 int32_t nfcNotDisturbOff = 0;
128 int32_t nfcNotDisturbOn = 1;
129 KITS::ErrorCode errCode = dataShare->GetValue(nfcNotDisturb, NFC_NOT_DISTURB_KEYWORD, value);
130 if (errCode == KITS::ERR_NFC_DATABASE_NULL) {
131 ErrorLog("fail to get datashare proxy.");
132 return false; // NFC not disturb switch is off by default.
133 }
134 if (value == INVALID_VALUE) {
135 WarnLog("NFC not disturb switch is off by default.");
136 dataShare->SetValue(nfcNotDisturb, NFC_NOT_DISTURB_KEYWORD, nfcNotDisturbOff);
137 dataShare->GetValue(nfcNotDisturb, NFC_NOT_DISTURB_KEYWORD, value);
138 }
139
140 // value = 1 : button on(not disturb, no banner), value = 0 : button off(banner on).
141 InfoLog("NFC notification not disturb button value %{public}d", value);
142 return (value == nfcNotDisturbOn);
143 }
144
OnNotificationButtonClicked(int notificationId)145 void NfcNotificationPublisher::OnNotificationButtonClicked(int notificationId)
146 {
147 std::lock_guard<std::mutex> lock(mutex_);
148 if (nfcService_.expired()) {
149 ErrorLog("nfc service expired, fail to callback.");
150 return;
151 }
152 std::weak_ptr<TAG::TagDispatcher> tagDispatcher = nfcService_.lock()->GetTagDispatcher();
153 if (tagDispatcher.expired()) {
154 ErrorLog("tagDispatcher expired, fail to inform button clicking");
155 return;
156 }
157 tagDispatcher.lock()->OnNotificationButtonClicked(notificationId);
158 }
159 } // namespace TAG
160 } // namespace NFC
161 } // namespace OHOS