• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 #define API __attribute__((visibility("default")))
17 
18 #include "notification_peripheral.h"
19 #include "edm_errors.h"
20 #include "file_ex.h"
21 #include "hilog_wrapper.h"
22 #include "locale_config.h"
23 #include "locale_info.h"
24 #include "notification_helper.h"
25 #include "notification_locale.h"
26 #include "os_account_manager.h"
27 #include "securec.h"
28 #include "want_agent_helper.h"
29 #include "want_agent_info.h"
30 #include <cJSON.h>
31 #include <map>
32 #include <unistd.h>
33 
34 namespace OHOS {
35 namespace ExternalDeviceManager {
36 static const std::string ENTITIES = "entity.system.browsable";
37 static const std::string ACTION = "ohos.want.action.viewData";
38 const int32_t NOTIFICATION_SERVICE_SYS_ABILITY_ID = 3085;
39 const int32_t NOTIFICATION_CONTROL_DIALOG_FLAG = 1 << 9;
40 constexpr const char *PERIPHERAL_ICON_PATH = "system/etc/peripheral/resources/peripheral_fault_icon.png";
41 
GetInstance()42 DeviceNotification &DeviceNotification::GetInstance()
43 {
44     static DeviceNotification instance;
45     return instance;
46 }
47 
HandleNotification(const FaultInfo & faultInfo)48 bool DeviceNotification::HandleNotification(const FaultInfo &faultInfo)
49 {
50     NotificationLocale::GetInstance().ParseLocaleCfg();
51     NotificationLocale::GetInstance().UpdateStringMap();
52     FaultInfo notifCfg = FillNotificationCfg(faultInfo);
53     if (notifCfg.title.empty() || notifCfg.msg.empty()) {
54         EDM_LOGE(MODULE_SERVICE, "Invalid notification: missing title or message");
55         return false;
56     }
57 
58     if (!PeripheralDeviceNotification(notifCfg)) {
59         EDM_LOGE(MODULE_SERVICE, "Failed to send peripheral notification");
60         return false;
61     }
62     return true;
63 }
64 
SetTitleAndText(std::shared_ptr<Notification::NotificationNormalContent> content,const std::string & title,const std::string & text)65 static bool SetTitleAndText(std::shared_ptr<Notification::NotificationNormalContent> content,
66                             const std::string &title, const std::string &text)
67 {
68     if (content == nullptr) {
69         EDM_LOGE(MODULE_SERVICE, "Notification normal content nullptr");
70         return false;
71     }
72 
73     content->SetTitle(title);
74     content->SetText(text);
75     return true;
76 }
77 
SetBasicOption(Notification::NotificationRequest & request)78 static void SetBasicOption(Notification::NotificationRequest &request)
79 {
80     request.SetCreatorUid(NOTIFICATION_SERVICE_SYS_ABILITY_ID);
81     int32_t userId = 0;
82     AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(NOTIFICATION_SERVICE_SYS_ABILITY_ID, userId);
83     request.SetCreatorPid(getpid());
84     request.SetCreatorUserId(userId);
85     request.SetInProgress(true);
86     request.SetUnremovable(true);
87     request.SetTapDismissed(true);
88     request.SetSlotType(OHOS::Notification::NotificationConstant::SlotType::SOCIAL_COMMUNICATION);
89     request.SetNotificationControlFlags(NOTIFICATION_CONTROL_DIALOG_FLAG);
90 }
91 
SetWantAgent(OHOS::Notification::NotificationRequest & request,const std::string & uri)92 static void SetWantAgent(OHOS::Notification::NotificationRequest &request, const std::string &uri)
93 {
94     auto want = std::make_shared<AAFwk::Want>();
95     want->SetAction(ACTION);
96     want->SetUri(uri);
97     want->AddEntity(ENTITIES);
98     std::vector<std::shared_ptr<AAFwk::Want>> wants;
99     wants.push_back(want);
100 
101     std::vector<AbilityRuntime::WantAgent::WantAgentConstant::Flags> flags;
102     flags.push_back(AbilityRuntime::WantAgent::WantAgentConstant::Flags::CONSTANT_FLAG);
103 
104     AbilityRuntime::WantAgent::WantAgentInfo wantAgentInfo(
105         0, AbilityRuntime::WantAgent::WantAgentConstant::OperationType::START_ABILITY, flags, wants, nullptr);
106     auto wantAgent = AbilityRuntime::WantAgent::WantAgentHelper::GetWantAgent(wantAgentInfo);
107     request.SetWantAgent(wantAgent);
108 }
109 
GetPixelMap(const std::string & path)110 bool DeviceNotification::GetPixelMap(const std::string &path)
111 {
112     if (access(path.c_str(), F_OK) != 0) {
113         EDM_LOGE(MODULE_DEV_MGR, "Peripheral icon file path not exists.");
114         iconPixelMap_ = nullptr;
115         return false;
116     }
117     uint32_t errorCode = 0;
118     Media::SourceOptions opts;
119     opts.formatHint = "image/png";
120     std::unique_ptr<Media::ImageSource> imageSource = Media::ImageSource::CreateImageSource(path, opts, errorCode);
121     if (imageSource == nullptr) {
122         EDM_LOGE(MODULE_DEV_MGR, "ImageSource nullptr");
123         iconPixelMap_ = nullptr;
124         return false;
125     }
126     Media::DecodeOptions decodeOpts;
127     std::unique_ptr<Media::PixelMap> pixelMap = imageSource->CreatePixelMap(decodeOpts, errorCode);
128     iconPixelMap_ = std::move(pixelMap);
129     return true;
130 }
131 
FillNotificationCfg(const FaultInfo & faultInfo)132 FaultInfo DeviceNotification::FillNotificationCfg(const FaultInfo &faultInfo)
133 {
134     auto &localeConfig = NotificationLocale::GetInstance();
135     FaultInfo temp(faultInfo);
136 
137     temp.title = localeConfig.GetValueByKey(faultInfo.title);
138     temp.msg = localeConfig.GetValueByKey(faultInfo.msg);
139     return temp;
140 }
141 
PeripheralDeviceNotification(const FaultInfo & faultInfo)142 bool DeviceNotification::PeripheralDeviceNotification(const FaultInfo &faultInfo)
143 {
144     EDM_LOGD(MODULE_SERVICE, "Start PeripheralDeviceNotification %{public}s", faultInfo.GetInfo().c_str());
145     std::shared_ptr<Notification::NotificationNormalContent> content =
146         std::make_shared<Notification::NotificationNormalContent>();
147     if (content == nullptr) {
148         EDM_LOGE(MODULE_SERVICE, "Failed to create NotificationNormalContent");
149         return false;
150     }
151 
152     if (!SetTitleAndText(content, faultInfo.title, faultInfo.msg)) {
153         EDM_LOGE(MODULE_SERVICE, "Failed to set title and text");
154         return false;
155     }
156 
157     std::shared_ptr<Notification::NotificationContent> notificationContent =
158         std::make_shared<Notification::NotificationContent>(content);
159     if (notificationContent == nullptr) {
160         EDM_LOGE(MODULE_SERVICE, "Failed to create NotificationContent");
161         return false;
162     }
163 
164     if (!GetPixelMap(PERIPHERAL_ICON_PATH)) {
165         EDM_LOGE(MODULE_SERVICE, "Failed to get peripheral icon pixel map");
166         return false;
167     }
168 
169     int32_t notificationId = static_cast<int32_t>(std::hash<std::string>()(faultInfo.title));
170     Notification::NotificationRequest request(notificationId);
171     if (iconPixelMap_ != nullptr) {
172         request.SetLittleIcon(iconPixelMap_);
173         request.SetBadgeIconStyle(Notification::NotificationRequest::BadgeStyle::LITTLE);
174     }
175 
176     request.SetContent(notificationContent);
177     SetBasicOption(request);
178     SetWantAgent(request, faultInfo.uri);
179     Notification::NotificationHelper::PublishNotification(request);
180     return true;
181 }
182 } // namespace ExternalDeviceManager
183 } // namespace OHOS
184