• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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> &notification,
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 }