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.h"
17
18 #include <map>
19 #include <set>
20
21 #include "cJSON.h"
22 #include "common_event_manager.h"
23 #include "file_ex.h"
24 #include "locale_config.h"
25 #include "locale_info.h"
26 #include "loghelper.h"
27 #include "nfc_sdk_common.h"
28 #include "securec.h"
29 #include "want_agent_helper.h"
30 #include "want_agent_info.h"
31
32 #ifdef DEBUG
33 #undef DEBUG
34 #endif
35 #include "notification_helper.h"
36
37 namespace OHOS {
38 namespace NFC {
39 namespace TAG {
40 enum NfcNotificationId : int {
41 NFC_TAG_DEFAULT_NTF_ID = 114000,
42 NFC_BT_NOTIFICATION_ID = 114001,
43 NFC_WIFI_NOTIFICATION_ID = 114002,
44 NFC_TRANSPORT_CARD_NOTIFICATION_ID = 114003,
45 NFC_BROWSER_NOTIFICATION_ID = 114004,
46 NFC_HCE_AID_CONFLICTED_ID = 114005,
47 NFC_NO_HAP_SUPPORTED_NOTIFICATION_ID = 114006,
48
49 // add NTF ID type before NFC_NTF_END
50 NFC_NTF_END,
51 };
52
53 const std::set<int> NFC_NTF_ID_WHITELIST = {
54 NFC_BT_NOTIFICATION_ID,
55 NFC_WIFI_NOTIFICATION_ID,
56 NFC_TRANSPORT_CARD_NOTIFICATION_ID
57 };
58
59 const int MAX_BUFF_LEN = 500;
60 const int NFC_UNIT_CHANGE_CONSTANT = 100;
61 const int NTF_AUTO_DELETE_TIME = 10000;
62 const int MAX_RES_VEC_LEN = 100;
63 const int NFC_SERVICE_UID = 1027;
64
65 // use this flag to control notification banners
66 // bit 4 represents vibration control: 1-off, 0-on
67 // bit 0 represents voice control: 1-off, 0-on
68 const uint32_t NFC_NTF_CONTROL_FLAG = 1 << 4 | 1;
69 // 1 << 9 represents turning on the banner switch for System Ability.
70 const uint32_t NFC_NTF_BANNER_SWITCH = 1 << 9;
71
72 constexpr const char* NFC_ICON_PATH = "system/etc/nfc/resources/base/media/nfc_icon.png";
73 constexpr const char* NFC_LANGUAGE_MAP_PATH = "system/etc/nfc/resources/base/profile/nfc_language_map.json";
74 constexpr const char* NFC_DEFAULT_LANGUAGE_FILE_PATH = "zh_CN";
75 constexpr const char* NFC_LANGUAGE_FILEPATH_PREFIX = "system/etc/nfc/resources/";
76 constexpr const char* NFC_LANGUAGE_FILEPATH_SUFFIX = "/element/string.json";
77 constexpr const char* NFC_ZHTW_LANGUAGE_FILE_PATH = "zh_TW";
78 constexpr const char* NFC_ZHHANT_LANGUAGE_FILE_PATH = "zh-Hant"; // The language type is Traditional Chinese
79 constexpr const char* NFC_ZHTW_REGION = "TW";
80
81 constexpr const char* KEY_LANGUAGE_MAP = "nfc_language_map";
82 constexpr const char* KEY_SYSTEM_LANGUAGE = "system_language";
83 constexpr const char* KEY_FILE_PATH = "file_path";
84
85 constexpr const char* KEY_STRING = "string";
86 constexpr const char* KEY_NAME = "name";
87 constexpr const char* KEY_VALUE = "value";
88
89 constexpr const char* KEY_TAG_DEFAULT_NTF_TITLE = "DefaultTitle";
90 constexpr const char* KEY_TAG_DEFAULT_NTF_TEXT = "DefaultText";
91 constexpr const char* KEY_TRANSPORT_CARD_NTF_TITLE = "TransportCardTitle";
92 constexpr const char* KEY_TRANSPORT_CARD_NTF_TEXT = "TransportCardText";
93 constexpr const char* KEY_NFC_WIFI_NTF_TITLE = "NfcWifiNtfTitle";
94 constexpr const char* KEY_NFC_WIFI_NTF_TEXT = "NfcWifiNtfText";
95 constexpr const char* KEY_ACTION_BUTTON_NAME = "ActionButtonName";
96 constexpr const char* KEY_NFC_WIFI_BUTTON_NAME = "NfcWifiButtonName";
97 constexpr const char* KEY_NFC_BT_NTF_TITLE = "NfcBtNtfTitle";
98 constexpr const char* KEY_NFC_BT_NTF_TEXT = "NfcBtNtfText";
99 constexpr const char* KEY_NFC_BT_BUTTON_NAME = "NfcBtButtonName";
100 constexpr const char* NFC_OPEN_LINK_BUTTON_NAME = "NfcOpenLinkButtonName";
101 constexpr const char* NFC_OPEN_LINK_TEXT_HEAD = "NfcOpenLinkTextHead";
102 constexpr const char* KEY_HCE_AID_CONFLICTED_TITLE = "NfcHceAidConflictedTitle";
103 constexpr const char* KEY_HCE_AID_CONFLICTED_TEXT = "NfcHceAidConflictedText";
104 constexpr const char* KEY_NO_HAP_TITLE = "NoHapSupportedNtfTitle";
105 constexpr const char* KEY_NO_HAP_TEXT = "NoHapSupportedNtfText";
106 constexpr const char* KEY_NO_HAP_BUTTON_NAME = "NoHapSupportedNtfButtonName";
107
108 constexpr const char* COMMON_EVENT_HIDE_DROPDOWN_WINDOW = "sceneboard.event.HIDE_DROPDOWN_WINDOW";
109
110 static std::string g_sysLanguage = "";
111 static std::string g_sysRegion = "";
112 static std::map<std::string, std::string> g_resourceMap;
113 static std::mutex g_callbackMutex {};
114 static NfcNtfCallback g_ntfCallback = nullptr;
115
116 class NfcNotificationSubscriber : public Notification::NotificationSubscriber {
PublishHideDropDownWindowEvent()117 void PublishHideDropDownWindowEvent()
118 {
119 AAFwk::Want want;
120 want.SetAction(COMMON_EVENT_HIDE_DROPDOWN_WINDOW);
121 EventFwk::CommonEventData commonData {want};
122 EventFwk::CommonEventPublishInfo publishInfo;
123 bool isSuccess = EventFwk::CommonEventManager::PublishCommonEvent(commonData, publishInfo, nullptr);
124 InfoLog("isSuccess: %{public}d", isSuccess);
125 }
OnConnected()126 void OnConnected() {}
OnDisconnected()127 void OnDisconnected() {}
OnUpdate(const std::shared_ptr<Notification::NotificationSortingMap> & sortingMap)128 void OnUpdate(const std::shared_ptr<Notification::NotificationSortingMap> &sortingMap) {}
OnDoNotDisturbDateChange(const std::shared_ptr<Notification::NotificationDoNotDisturbDate> & date)129 void OnDoNotDisturbDateChange(const std::shared_ptr<Notification::NotificationDoNotDisturbDate> &date) {}
OnEnabledNotificationChanged(const std::shared_ptr<Notification::EnabledNotificationCallbackData> & callbackData)130 void OnEnabledNotificationChanged(
131 const std::shared_ptr<Notification::EnabledNotificationCallbackData> &callbackData) {}
OnDied()132 void OnDied() {}
OnCanceled(const std::shared_ptr<OHOS::Notification::Notification> & request,const std::shared_ptr<Notification::NotificationSortingMap> & sortingMap,int deleteReason)133 void OnCanceled(const std::shared_ptr<OHOS::Notification::Notification> &request,
134 const std::shared_ptr<Notification::NotificationSortingMap> &sortingMap, int deleteReason)
135 {
136 int creatorUid = request->GetUid();
137 int notificationId = request->GetId();
138 InfoLog("Oncanceled, creatorUid = %{public}d, notificationId = %{public}d, deleteReason = %{public}d",
139 creatorUid, notificationId, deleteReason);
140
141 std::lock_guard<std::mutex> lock(g_callbackMutex);
142 if (creatorUid == NFC_SERVICE_UID && deleteReason == Notification::NotificationConstant::CLICK_REASON_DELETE &&
143 g_ntfCallback) {
144 PublishHideDropDownWindowEvent();
145 g_ntfCallback(notificationId);
146 }
147 }
OnConsumed(const std::shared_ptr<OHOS::Notification::Notification> & notification,const std::shared_ptr<Notification::NotificationSortingMap> & sortingMap)148 void OnConsumed(const std::shared_ptr<OHOS::Notification::Notification> ¬ification,
149 const std::shared_ptr<Notification::NotificationSortingMap> &sortingMap) {}
OnBadgeChanged(const std::shared_ptr<Notification::BadgeNumberCallbackData> & badgeData)150 void OnBadgeChanged(const std::shared_ptr<Notification::BadgeNumberCallbackData> &badgeData) {}
OnBadgeEnabledChanged(const sptr<Notification::EnabledNotificationCallbackData> & callbackData)151 void OnBadgeEnabledChanged(const sptr<Notification::EnabledNotificationCallbackData> &callbackData) {}
OnBatchCanceled(const std::vector<std::shared_ptr<OHOS::Notification::Notification>> & requestList,const std::shared_ptr<Notification::NotificationSortingMap> & sortingMap,int32_t deleteReason)152 void OnBatchCanceled(const std::vector<std::shared_ptr<OHOS::Notification::Notification>> &requestList,
153 const std::shared_ptr<Notification::NotificationSortingMap> &sortingMap, int32_t deleteReason) {}
154 };
155
156 static std::shared_ptr<NfcNotificationSubscriber> g_notificationSubscriber
157 = std::make_shared<NfcNotificationSubscriber>();
158
UpdateResourceMap(const std::string & resourcePath)159 static void UpdateResourceMap(const std::string &resourcePath)
160 {
161 InfoLog("Reading resource string from json config.");
162
163 std::string content;
164 LoadStringFromFile(resourcePath, content);
165 cJSON *json = cJSON_Parse(content.c_str());
166 if (json == nullptr) {
167 ErrorLog("json nullptr.");
168 return;
169 }
170
171 cJSON *resJson = cJSON_GetObjectItemCaseSensitive(json, KEY_STRING);
172 if (resJson == nullptr || cJSON_GetArraySize(resJson) > MAX_RES_VEC_LEN) {
173 ErrorLog("fail to parse res json");
174 cJSON_Delete(json);
175 return;
176 }
177
178 g_resourceMap.clear();
179 cJSON *resJsonEach = nullptr;
180 cJSON_ArrayForEach(resJsonEach, resJson) {
181 cJSON *key = cJSON_GetObjectItemCaseSensitive(resJsonEach, KEY_NAME);
182 if (key == nullptr || !cJSON_IsString(key)) {
183 ErrorLog("json param not string");
184 cJSON_Delete(json);
185 return;
186 }
187
188 cJSON *value = cJSON_GetObjectItemCaseSensitive(resJsonEach, KEY_VALUE);
189 if (value == nullptr || !cJSON_IsString(value)) {
190 ErrorLog("json param not string");
191 cJSON_Delete(json);
192 return;
193 }
194
195 g_resourceMap.insert(std::pair<std::string, std::string>(key->valuestring, value->valuestring));
196 }
197 cJSON_Delete(json);
198 }
199
GetLanguageFilePath(const std::string & sysLanguage,const std::string & sysRegion)200 static std::string GetLanguageFilePath(const std::string &sysLanguage, const std::string &sysRegion)
201 {
202 InfoLog("Reading language file path from json config.");
203 std::string content;
204 std::string filePath = NFC_DEFAULT_LANGUAGE_FILE_PATH;
205 LoadStringFromFile(NFC_LANGUAGE_MAP_PATH, content);
206 cJSON *json = cJSON_Parse(content.c_str());
207 if (json == nullptr) {
208 ErrorLog("json nullptr.");
209 return filePath;
210 }
211
212 cJSON *resJson = cJSON_GetObjectItemCaseSensitive(json, KEY_LANGUAGE_MAP);
213 if (resJson == nullptr || !cJSON_IsArray(resJson)) {
214 ErrorLog("fail to parse KEY_LANGUAGE_MAP");
215 cJSON_Delete(json);
216 return filePath;
217 }
218
219 if (sysLanguage == NFC_ZHHANT_LANGUAGE_FILE_PATH && sysRegion == NFC_ZHTW_REGION) {
220 cJSON_Delete(json);
221 InfoLog("file path is zh-TW");
222 return NFC_ZHTW_LANGUAGE_FILE_PATH;
223 }
224
225 cJSON *resJsonEach = nullptr;
226 cJSON_ArrayForEach(resJsonEach, resJson) {
227 cJSON *key = cJSON_GetObjectItemCaseSensitive(resJsonEach, KEY_SYSTEM_LANGUAGE);
228 if (key == nullptr || !cJSON_IsString(key)) {
229 ErrorLog("json param KEY_SYSTEM_LANGUAGE not string");
230 continue;
231 }
232 if (key->valuestring != sysLanguage) {
233 continue;
234 }
235
236 cJSON *value = cJSON_GetObjectItemCaseSensitive(resJsonEach, KEY_FILE_PATH);
237 if (value == nullptr || !cJSON_IsString(value)) {
238 ErrorLog("json param KEY_FILE_PATH not string");
239 cJSON_Delete(json);
240 return filePath;
241 }
242
243 filePath = value->valuestring;
244 break;
245 }
246 cJSON_Delete(json);
247 InfoLog("file path %{public}s", filePath.c_str());
248 return filePath;
249 }
250
UpdateResourceMapByLanguage()251 static void UpdateResourceMapByLanguage()
252 {
253 std::string curSysLanguage = Global::I18n::LocaleConfig::GetSystemLanguage();
254 std::string curSysRegion = Global::I18n::LocaleConfig::GetSystemRegion();
255 if (g_sysLanguage == curSysLanguage && curSysRegion == g_sysRegion) {
256 DebugLog("same language environment[%{public}s], region[%{public}s] ,no need to update resource map.",
257 curSysLanguage.c_str(), curSysRegion.c_str());
258 return;
259 }
260
261 InfoLog("current system language[%{public}s], region[%{public}s] changes, should update resource map",
262 curSysLanguage.c_str(), curSysRegion.c_str());
263 g_sysLanguage = curSysLanguage;
264 g_sysRegion = curSysRegion;
265
266 std::string filePath = NFC_LANGUAGE_FILEPATH_PREFIX +
267 GetLanguageFilePath(g_sysLanguage, g_sysRegion) +
268 NFC_LANGUAGE_FILEPATH_SUFFIX;
269 UpdateResourceMap(filePath);
270 }
271
GetTrafficCardNotificationText(const std::string & cardName,int balance)272 static std::string GetTrafficCardNotificationText(const std::string &cardName, int balance)
273 {
274 char buf[MAX_BUFF_LEN] = {0};
275 int ret = sprintf_s(buf, MAX_BUFF_LEN, g_resourceMap[KEY_TRANSPORT_CARD_NTF_TEXT].c_str(),
276 g_resourceMap[cardName].c_str(), static_cast<float>(balance) / NFC_UNIT_CHANGE_CONSTANT);
277 if (ret <= 0) {
278 ErrorLog("sprintf_s failed, ret[%{public}d]", ret);
279 return "";
280 }
281
282 return std::string(buf);
283 }
284
285 #ifdef NDEF_WIFI_ENABLED
GetWifiNotificationText(const std::string & ssid)286 static std::string GetWifiNotificationText(const std::string &ssid)
287 {
288 char buf[MAX_BUFF_LEN] = {0};
289 int ret = sprintf_s(buf, MAX_BUFF_LEN, g_resourceMap[KEY_NFC_WIFI_NTF_TEXT].c_str(), ssid.c_str());
290 if (ret <= 0) {
291 ErrorLog("sprintf_s failed, ret[%{public}d]", ret);
292 return "";
293 }
294
295 return std::string(buf);
296 }
297 #endif
298
299 #ifdef NDEF_BT_ENABLED
GetBtNotificationText(const std::string & name)300 static std::string GetBtNotificationText(const std::string &name)
301 {
302 char buf[MAX_BUFF_LEN] = {0};
303 int ret = sprintf_s(buf, MAX_BUFF_LEN, g_resourceMap[KEY_NFC_BT_NTF_TEXT].c_str(), name.c_str());
304 if (ret <= 0) {
305 ErrorLog("sprintf_s failed, ret[%{public}d]", ret);
306 return "";
307 }
308
309 return std::string(buf);
310 }
311 #endif
312
SetTitleAndTextForOtherNotificationId(int notificationId,std::shared_ptr<Notification::NotificationNormalContent> nfcContent,const std::string & name,int balance)313 static bool SetTitleAndTextForOtherNotificationId(int notificationId,
314 std::shared_ptr<Notification::NotificationNormalContent> nfcContent, const std::string &name, int balance)
315 {
316 switch (notificationId) {
317 case NFC_TAG_DEFAULT_NTF_ID:
318 if (g_resourceMap.find(KEY_TAG_DEFAULT_NTF_TITLE) != g_resourceMap.end() &&
319 g_resourceMap.find(KEY_TAG_DEFAULT_NTF_TEXT) != g_resourceMap.end()) {
320 nfcContent->SetTitle(g_resourceMap[KEY_TAG_DEFAULT_NTF_TITLE]);
321 nfcContent->SetText(g_resourceMap[KEY_TAG_DEFAULT_NTF_TEXT]);
322 }
323 break;
324 case NFC_BROWSER_NOTIFICATION_ID:
325 if (g_resourceMap.find(KEY_TAG_DEFAULT_NTF_TITLE) != g_resourceMap.end() &&
326 g_resourceMap.find(NFC_OPEN_LINK_TEXT_HEAD) != g_resourceMap.end()) {
327 nfcContent->SetTitle(g_resourceMap[KEY_TAG_DEFAULT_NTF_TITLE]);
328 nfcContent->SetText(g_resourceMap[NFC_OPEN_LINK_TEXT_HEAD] + name);
329 }
330 break;
331 case NFC_HCE_AID_CONFLICTED_ID:
332 if (g_resourceMap.find(KEY_HCE_AID_CONFLICTED_TITLE) != g_resourceMap.end() &&
333 g_resourceMap.find(KEY_HCE_AID_CONFLICTED_TEXT) != g_resourceMap.end()) {
334 nfcContent->SetTitle(g_resourceMap[KEY_HCE_AID_CONFLICTED_TITLE]);
335 nfcContent->SetText(g_resourceMap[KEY_HCE_AID_CONFLICTED_TEXT]);
336 }
337 break;
338 case NFC_NO_HAP_SUPPORTED_NOTIFICATION_ID:
339 if (g_resourceMap.find(KEY_NO_HAP_TITLE) != g_resourceMap.end() &&
340 g_resourceMap.find(KEY_NO_HAP_TEXT) != g_resourceMap.end()) {
341 nfcContent->SetTitle(g_resourceMap[KEY_NO_HAP_TITLE]);
342 nfcContent->SetText(g_resourceMap[KEY_NO_HAP_TEXT]);
343 }
344 break;
345 default:
346 WarnLog("unknown notification ID");
347 return false;
348 }
349 return true;
350 }
351
SetTitleAndText(int notificationId,std::shared_ptr<Notification::NotificationNormalContent> nfcContent,const std::string & name,int balance)352 static bool SetTitleAndText(int notificationId,
353 std::shared_ptr<Notification::NotificationNormalContent> nfcContent, const std::string &name, int balance)
354 {
355 if (nfcContent == nullptr) {
356 ErrorLog("notification normal content nullptr");
357 return false;
358 }
359 UpdateResourceMapByLanguage();
360
361 switch (notificationId) {
362 case NFC_TRANSPORT_CARD_NOTIFICATION_ID:
363 if (g_resourceMap.find(KEY_TRANSPORT_CARD_NTF_TITLE) != g_resourceMap.end() &&
364 g_resourceMap.find(KEY_TRANSPORT_CARD_NTF_TEXT) != g_resourceMap.end() &&
365 g_resourceMap.find(name) != g_resourceMap.end()) {
366 nfcContent->SetTitle(g_resourceMap[KEY_TRANSPORT_CARD_NTF_TITLE]);
367 nfcContent->SetText(GetTrafficCardNotificationText(name, balance));
368 }
369 break;
370 case NFC_WIFI_NOTIFICATION_ID:
371 #ifdef NDEF_WIFI_ENABLED
372 if (g_resourceMap.find(KEY_NFC_WIFI_NTF_TITLE) != g_resourceMap.end() &&
373 g_resourceMap.find(KEY_NFC_WIFI_NTF_TEXT) != g_resourceMap.end()) {
374 nfcContent->SetTitle(g_resourceMap[KEY_NFC_WIFI_NTF_TITLE]);
375 nfcContent->SetText(GetWifiNotificationText(name));
376 }
377 break;
378 #else
379 ErrorLog("nfc wifi notification not supported");
380 return false;
381 #endif
382 case NFC_BT_NOTIFICATION_ID:
383 #ifdef NDEF_BT_ENABLED
384 if (g_resourceMap.find(KEY_NFC_BT_NTF_TITLE) != g_resourceMap.end() &&
385 g_resourceMap.find(KEY_NFC_BT_NTF_TEXT) != g_resourceMap.end()) {
386 nfcContent->SetTitle(g_resourceMap[KEY_NFC_BT_NTF_TITLE]);
387 nfcContent->SetText(GetBtNotificationText(name));
388 }
389 break;
390 #else
391 ErrorLog("nfc bt notification not supported");
392 return false;
393 #endif
394 default:
395 return SetTitleAndTextForOtherNotificationId(notificationId, nfcContent, name, balance);
396 }
397 return true;
398 }
399
GetButtonName(int notificationId)400 static std::string GetButtonName(int notificationId)
401 {
402 switch (notificationId) {
403 case NFC_BT_NOTIFICATION_ID:
404 if (g_resourceMap.find(KEY_NFC_BT_BUTTON_NAME) != g_resourceMap.end()) {
405 return g_resourceMap[KEY_NFC_BT_BUTTON_NAME];
406 }
407 return "";
408 case NFC_WIFI_NOTIFICATION_ID:
409 if (g_resourceMap.find(KEY_NFC_WIFI_BUTTON_NAME) != g_resourceMap.end()) {
410 return g_resourceMap[KEY_NFC_WIFI_BUTTON_NAME];
411 }
412 return "";
413 case NFC_BROWSER_NOTIFICATION_ID:
414 if (g_resourceMap.find(NFC_OPEN_LINK_BUTTON_NAME) != g_resourceMap.end()) {
415 return g_resourceMap[NFC_OPEN_LINK_BUTTON_NAME];
416 }
417 return "";
418 case NFC_NO_HAP_SUPPORTED_NOTIFICATION_ID:
419 if (g_resourceMap.find(KEY_NO_HAP_BUTTON_NAME) != g_resourceMap.end()) {
420 return g_resourceMap[KEY_NO_HAP_BUTTON_NAME];
421 }
422 return "";
423 default:
424 if (g_resourceMap.find(KEY_ACTION_BUTTON_NAME) != g_resourceMap.end()) {
425 return g_resourceMap[KEY_ACTION_BUTTON_NAME];
426 }
427 return "";
428 }
429 }
430
SetActionButton(const std::string & buttonName,Notification::NotificationRequest & request)431 static void SetActionButton(const std::string& buttonName, Notification::NotificationRequest& request)
432 {
433 auto want = std::make_shared<AAFwk::Want>();
434 std::vector<std::shared_ptr<AAFwk::Want>> wants;
435 wants.push_back(want);
436 std::vector<AbilityRuntime::WantAgent::WantAgentConstant::Flags> flags;
437 flags.push_back(AbilityRuntime::WantAgent::WantAgentConstant::Flags::CONSTANT_FLAG);
438 AbilityRuntime::WantAgent::WantAgentInfo wantAgentInfo(
439 0, AbilityRuntime::WantAgent::WantAgentConstant::OperationType::UNKNOWN_TYPE,
440 flags, wants, nullptr
441 );
442 auto wantAgentDeal = AbilityRuntime::WantAgent::WantAgentHelper::GetWantAgent(wantAgentInfo);
443 std::shared_ptr<Notification::NotificationActionButton> actionButtonDeal =
444 Notification::NotificationActionButton::Create(nullptr, buttonName, wantAgentDeal);
445 if (actionButtonDeal == nullptr) {
446 ErrorLog("get notification actionButton nullptr");
447 return;
448 }
449 request.AddActionButton(actionButtonDeal);
450 }
451
GetAutoDeleteTime()452 static int64_t GetAutoDeleteTime()
453 {
454 auto now = std::chrono::system_clock::now();
455 auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
456 return duration.count() + NTF_AUTO_DELETE_TIME;
457 }
458
IsNtfIdWhiteList(int notificationId)459 static bool IsNtfIdWhiteList(int notificationId)
460 {
461 return (NFC_NTF_ID_WHITELIST.find(notificationId) != NFC_NTF_ID_WHITELIST.end());
462 }
463
SetBasicOption(Notification::NotificationRequest & request,int notificationId,bool isNfcNotDisturb)464 static void SetBasicOption(Notification::NotificationRequest &request, int notificationId, bool isNfcNotDisturb)
465 {
466 request.SetCreatorUid(NFC_SERVICE_UID);
467 request.SetAutoDeletedTime(GetAutoDeleteTime());
468 request.SetTapDismissed(true);
469 request.SetSlotType(OHOS::Notification::NotificationConstant::SlotType::SOCIAL_COMMUNICATION);
470
471 uint32_t controlFlag = NFC_NTF_CONTROL_FLAG;
472 if (!isNfcNotDisturb || IsNtfIdWhiteList(notificationId)) {
473 InfoLog("turn on banner switch for NFC ntf.");
474 controlFlag = NFC_NTF_BANNER_SWITCH;
475 }
476 InfoLog("controlFlag = 0x%{public}x", controlFlag);
477 request.SetNotificationControlFlags(controlFlag);
478 }
479
SetNfcRequestContent(Notification::NotificationRequest & request,int notificationId,const std::string & name,int balance)480 static bool SetNfcRequestContent(
481 Notification::NotificationRequest &request, int notificationId, const std::string &name, int balance)
482 {
483 std::shared_ptr<Notification::NotificationNormalContent> nfcContent =
484 std::make_shared<Notification::NotificationNormalContent>();
485 if (nfcContent == nullptr) {
486 ErrorLog("get notification normal content nullptr");
487 return false;
488 }
489
490 if (!SetTitleAndText(notificationId, nfcContent, name, balance)) {
491 ErrorLog("error setting title and text");
492 return false;
493 }
494 std::shared_ptr<Notification::NotificationContent> content =
495 std::make_shared<Notification::NotificationContent>(nfcContent);
496 if (content == nullptr) {
497 ErrorLog("get notification content nullptr");
498 return false;
499 }
500 request.SetContent(content);
501 return true;
502 }
503
GetPixelMap(const std::string & path)504 void NfcNotification::GetPixelMap(const std::string &path)
505 {
506 if (nfcIconPixelMap_ != nullptr) {
507 InfoLog("nfc icon pixel map already exists.");
508 return;
509 }
510
511 if (!std::filesystem::exists(path)) {
512 ErrorLog("nfc icon file path not exists.");
513 nfcIconPixelMap_ = nullptr;
514 return;
515 }
516 uint32_t errorCode = 0;
517 Media::SourceOptions opts;
518 opts.formatHint = "image/png";
519 std::unique_ptr<Media::ImageSource> imageSource = Media::ImageSource::CreateImageSource(path, opts, errorCode);
520 if (imageSource == nullptr) {
521 ErrorLog("imageSource nullptr");
522 nfcIconPixelMap_ = nullptr;
523 return;
524 }
525 Media::DecodeOptions decodeOpts;
526 std::unique_ptr<Media::PixelMap> pixelMap = imageSource->CreatePixelMap(decodeOpts, errorCode);
527 nfcIconPixelMap_ = std::move(pixelMap);
528 }
529
GetInstance()530 NfcNotification& NfcNotification::GetInstance()
531 {
532 static NfcNotification instance;
533 return instance;
534 }
535
NfcNotification()536 NfcNotification::NfcNotification()
537 {
538 InfoLog("NfcNotification constructor enter.");
539 std::lock_guard<std::mutex> lock(mutex_);
540 // only need to subscribe notification once
541 int result = Notification::NotificationHelper::SubscribeNotification(*g_notificationSubscriber);
542 if (result != ERR_OK) {
543 ErrorLog("fail to subscribe notification");
544 }
545 UpdateResourceMapByLanguage();
546 }
547
~NfcNotification()548 NfcNotification::~NfcNotification()
549 {
550 InfoLog("NfcNotification destructor enter.");
551 // no operation to unsubscribe notification
552 }
553
PublishNfcNotification(bool isNfcNotDisturb,int notificationId,const std::string & name,int balance)554 void NfcNotification::PublishNfcNotification(
555 bool isNfcNotDisturb, int notificationId, const std::string &name, int balance)
556 {
557 if (notificationId >= NFC_NTF_END || notificationId < NFC_TAG_DEFAULT_NTF_ID) {
558 ErrorLog("invalid notification id.");
559 return;
560 }
561
562 std::lock_guard<std::mutex> lock(mutex_);
563 int ret = Notification::NotificationHelper::CancelAllNotifications();
564 InfoLog("Cancel all ntf result[%{public}d]", ret);
565
566 Notification::NotificationRequest request;
567 SetBasicOption(request, notificationId, isNfcNotDisturb);
568 if (!SetNfcRequestContent(request, notificationId, name, balance)) {
569 ErrorLog("fail to set request content.");
570 return;
571 }
572 request.SetNotificationId(notificationId);
573
574 GetPixelMap(NFC_ICON_PATH);
575 if (nfcIconPixelMap_ != nullptr) {
576 request.SetLittleIcon(nfcIconPixelMap_);
577 request.SetBadgeIconStyle(Notification::NotificationRequest::BadgeStyle::LITTLE);
578 }
579
580 std::string buttonName = GetButtonName(notificationId);
581 if (!buttonName.empty()) {
582 SetActionButton(buttonName, request);
583 }
584
585 ret = Notification::NotificationHelper::PublishNotification(request);
586 InfoLog("NFC service publish notification result = %{public}d", ret);
587 }
588
RegNotificationCallback(NfcNtfCallback callback)589 void NfcNotification::RegNotificationCallback(NfcNtfCallback callback)
590 {
591 std::lock_guard<std::mutex> lock(g_callbackMutex);
592 g_ntfCallback = callback;
593 }
594 } // namespace TAG
595 } // namespace NFC
596 } // namespace OHOS
597
RegNotificationCallback(NfcNtfCallback callback)598 void RegNotificationCallback(NfcNtfCallback callback)
599 {
600 OHOS::NFC::TAG::NfcNotification::GetInstance().RegNotificationCallback(callback);
601 }
602
PublishNfcNotification(bool isNfcNotDisturb,int notificationId,const std::string & name,int balance)603 void PublishNfcNotification(bool isNfcNotDisturb, int notificationId, const std::string &name, int balance)
604 {
605 InfoLog("Publishing nfc tag notification, id [%{public}d]", notificationId);
606 OHOS::NFC::TAG::NfcNotification::GetInstance().PublishNfcNotification(
607 isNfcNotDisturb, notificationId, name, balance);
608 }