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 "notification_icon_button.h"
17
18 #include <string> // for basic_string, operator+, basic_string<>...
19 #include <memory> // for shared_ptr, shared_ptr<>::element_type
20 #include <sstream>
21
22
23 #include "ans_image_util.h"
24 #include "ans_log_wrapper.h"
25 #include "nlohmann/json.hpp" // for json, basic_json<>::object_t, basic_json
26 #include "parcel.h" // for Parcel
27
28 namespace OHOS {
29 namespace Notification {
30 using ResourceVectorPtr = std::vector<std::shared_ptr<ResourceManager::Resource>>;
31
GetIconResource() const32 const std::shared_ptr<ResourceManager::Resource> NotificationIconButton::GetIconResource() const
33 {
34 return iconResource_;
35 }
36
SetIconResource(const std::shared_ptr<ResourceManager::Resource> & iconResource)37 void NotificationIconButton::SetIconResource(const std::shared_ptr<ResourceManager::Resource> &iconResource)
38 {
39 iconResource_ = iconResource;
40 }
41
GetIconImage() const42 const std::shared_ptr<Media::PixelMap> NotificationIconButton::GetIconImage() const
43 {
44 return iconImage_;
45 }
46
SetIconImage(const std::shared_ptr<Media::PixelMap> & iconImage)47 void NotificationIconButton::SetIconImage(const std::shared_ptr<Media::PixelMap> &iconImage)
48 {
49 iconImage_ = iconImage;
50 }
51
GetText() const52 std::string NotificationIconButton::GetText() const
53 {
54 return text_;
55 }
56
SetText(const std::string & text)57 void NotificationIconButton::SetText(const std::string &text)
58 {
59 text_ = text;
60 }
61
GetName() const62 std::string NotificationIconButton::GetName() const
63 {
64 return name_;
65 }
66
SetName(const std::string & name)67 void NotificationIconButton::SetName(const std::string &name)
68 {
69 name_ = name;
70 }
71
GetHidePanel() const72 bool NotificationIconButton::GetHidePanel() const
73 {
74 return hidePanel_;
75 }
76
SetHidePanel(bool hidePanel)77 void NotificationIconButton::SetHidePanel(bool hidePanel)
78 {
79 hidePanel_ = hidePanel;
80 }
81
ClearButtonIconsResource()82 void NotificationIconButton::ClearButtonIconsResource()
83 {
84 }
85
Dump()86 std::string NotificationIconButton::Dump()
87 {
88 return "NotificationIconButton {"
89 "name = " + name_ +
90 ", text = " + text_ +
91 ", hidePanel = " + std::to_string(hidePanel_) +
92 " }";
93 }
94
ToJson(nlohmann::json & jsonObject) const95 bool NotificationIconButton::ToJson(nlohmann::json &jsonObject) const
96 {
97 jsonObject["text"] = text_;
98 jsonObject["name"] = name_;
99 jsonObject["hidePanel"] = hidePanel_;
100
101 if (iconResource_ != nullptr) {
102 nlohmann::json resourceObj;
103 resourceObj["id"] = iconResource_->id;
104 resourceObj["bundleName"] = iconResource_->bundleName;
105 resourceObj["moduleName"] = iconResource_->moduleName;
106 jsonObject["iconResource"] = resourceObj;
107 }
108 jsonObject["iconImage"] = AnsImageUtil::PackImage(iconImage_);
109 return true;
110 }
111
FromJson(const nlohmann::json & jsonObject)112 NotificationIconButton *NotificationIconButton::FromJson(const nlohmann::json &jsonObject)
113 {
114 if (jsonObject.is_null() or !jsonObject.is_object()) {
115 ANS_LOGE("Invalid JSON object");
116 return nullptr;
117 }
118
119 auto *button = new (std::nothrow) NotificationIconButton();
120 if (button == nullptr) {
121 ANS_LOGE("Failed to create icon button");
122 return nullptr;
123 }
124
125 const auto &jsonEnd = jsonObject.cend();
126 if (jsonObject.find("text") != jsonEnd && jsonObject.at("text").is_string()) {
127 button->SetText(jsonObject.at("text").get<std::string>());
128 }
129
130 if (jsonObject.find("name") != jsonEnd && jsonObject.at("name").is_string()) {
131 button->SetName(jsonObject.at("name").get<std::string>());
132 }
133
134 if (jsonObject.find("hidePanel") != jsonEnd && jsonObject.at("hidePanel").is_boolean()) {
135 button->SetHidePanel(jsonObject.at("hidePanel").get<bool>());
136 }
137
138 if (jsonObject.find("iconResource") != jsonEnd) {
139 auto resources = jsonObject.at("iconResource");
140 auto resourceObj = std::make_shared<Global::Resource::ResourceManager::Resource>();
141 if (ResourceFromJson(resources, resourceObj)) {
142 button->SetIconResource(resourceObj);
143 }
144 auto pIcon = AnsImageUtil::UnPackImage(resources);
145 if (pIcon == nullptr) {
146 ANS_LOGE("Failed to parse button icon");
147 delete button;
148 } else {
149 button->SetIconImage(pIcon);
150 }
151 } else if (jsonObject.find("iconImage") != jsonEnd) {
152 auto resources = jsonObject.at("iconImage");
153 auto pIcon = AnsImageUtil::UnPackImage(resources);
154 if (pIcon == nullptr) {
155 ANS_LOGE("Failed to parse button icon");
156 delete button;
157 } else {
158 button->SetIconImage(pIcon);
159 }
160 }
161 return button;
162 }
163
ResourceFromJson(const nlohmann::json & resource,std::shared_ptr<ResourceManager::Resource> & resourceObj)164 bool NotificationIconButton::ResourceFromJson(const nlohmann::json &resource,
165 std::shared_ptr<ResourceManager::Resource>& resourceObj)
166 {
167 const auto &jsonEnd = resource.cend();
168 int resourceCount = BUTTON_RESOURCE_SIZE;
169 if (resource.find("bundleName") != jsonEnd && resource.at("bundleName").is_string()) {
170 resourceCount--;
171 resourceObj->bundleName = resource.at("bundleName").get<std::string>();
172 }
173 if (resource.find("moduleName") != jsonEnd && resource.at("moduleName").is_string()) {
174 resourceCount--;
175 resourceObj->moduleName = resource.at("moduleName").get<std::string>();
176 }
177 if (resource.find("id") != jsonEnd && resource.at("id").is_number_integer()) {
178 resourceCount--;
179 resourceObj->id = static_cast<uint32_t>(resource.at("id").get<int32_t>());
180 }
181 if (resourceCount == 0) {
182 return true;
183 }
184 ANS_LOGE("Resource from json failed.");
185 return false;
186 }
187
Marshalling(Parcel & parcel) const188 bool NotificationIconButton::Marshalling(Parcel &parcel) const
189 {
190 if (!parcel.WriteString(text_)) {
191 ANS_LOGE("Failed to write text");
192 return false;
193 }
194
195 if (!parcel.WriteString(name_)) {
196 ANS_LOGE("Failed to write name");
197 return false;
198 }
199
200 if (!parcel.WriteBool(hidePanel_)) {
201 ANS_LOGE("Failed to write hidePanel");
202 return false;
203 }
204
205 if (!WriteIconToParcel(parcel)) {
206 return false;
207 }
208
209 return true;
210 }
211
Unmarshalling(Parcel & parcel)212 NotificationIconButton *NotificationIconButton::Unmarshalling(Parcel &parcel)
213 {
214 NotificationIconButton *button = new (std::nothrow) NotificationIconButton();
215
216 if (button && !button->ReadFromParcel(parcel)) {
217 delete button;
218 button = nullptr;
219 }
220 return button;
221 }
222
ReadFromParcel(Parcel & parcel)223 bool NotificationIconButton::ReadFromParcel(Parcel &parcel)
224 {
225 if (!parcel.ReadString(text_)) {
226 ANS_LOGE("Failed to read text");
227 return false;
228 }
229
230 if (!parcel.ReadString(name_)) {
231 ANS_LOGE("Failed to read name");
232 return false;
233 }
234
235 if (!parcel.ReadBool(hidePanel_)) {
236 ANS_LOGE("Failed to read hidePanel");
237 return false;
238 }
239
240 bool valid {false};
241 valid = parcel.ReadBool();
242 if (valid) {
243 iconImage_ = std::shared_ptr<Media::PixelMap>(parcel.ReadParcelable<Media::PixelMap>());
244 if (!iconImage_) {
245 ANS_LOGE("Failed to read button icon.");
246 return false;
247 }
248 }
249
250 valid = parcel.ReadBool();
251 if (valid) {
252 if (!ReadResourceFromParcel(parcel, iconResource_)) {
253 ANS_LOGE("Failed to read button icon resource.");
254 return false;
255 }
256 }
257 return true;
258 }
259
WriteIconToParcel(Parcel & parcel) const260 bool NotificationIconButton::WriteIconToParcel(Parcel &parcel) const
261 {
262 bool valid {false};
263 valid = iconImage_ ? true : false;
264 if (!parcel.WriteBool(valid)) {
265 ANS_LOGE("Failed to write the flag which indicate whether button icon is null");
266 return false;
267 }
268 if (valid) {
269 if (!parcel.WriteParcelable(iconImage_.get())) {
270 ANS_LOGE("Failed to write iconImage.");
271 return false;
272 }
273 }
274
275 valid = iconResource_ ? true : false;
276 if (!parcel.WriteBool(valid)) {
277 ANS_LOGE("Failed to write the flag which indicate whether button icon resource is null");
278 return false;
279 }
280 if (valid) {
281 std::vector<std::string> iconResource = {};
282 iconResource.push_back(iconResource_->bundleName);
283 iconResource.push_back(iconResource_->moduleName);
284 iconResource.push_back(std::to_string(iconResource_->id));
285 if (!parcel.WriteStringVector(iconResource)) {
286 ANS_LOGE("Failed to write button icon resource");
287 return false;
288 }
289 }
290 return true;
291 }
292
ReadResourceFromParcel(Parcel & parcel,std::shared_ptr<ResourceManager::Resource> & resourceObj)293 bool NotificationIconButton::ReadResourceFromParcel(Parcel &parcel,
294 std::shared_ptr<ResourceManager::Resource> &resourceObj)
295 {
296 std::vector<std::string> iconsResource = {};
297 if (!parcel.ReadStringVector(&iconsResource)) {
298 ANS_LOGE("Failed to read button names");
299 return false;
300 }
301 if (iconsResource.size() < BUTTON_RESOURCE_SIZE) {
302 ANS_LOGE("Invalid input for button icons resource");
303 return false;
304 }
305 auto resource = std::make_shared<ResourceManager::Resource>();
306 resource->bundleName = iconsResource[RESOURCE_BUNDLENAME_INDEX];
307 resource->moduleName = iconsResource[RESOURCE_MODULENAME_INDEX];
308 std::stringstream sin(iconsResource[RESOURCE_ID_INDEX]);
309 int32_t checknum;
310 if (!(sin >> checknum)) {
311 ANS_LOGE("Invalid input for button icons resource");
312 return false;
313 }
314 resource->id = std::stoi(iconsResource[RESOURCE_ID_INDEX]);
315 resourceObj = resource;
316 return true;
317 }
318 }
319 }
320