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