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("null 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("null pIcon");
147 delete button;
148 button = nullptr;
149 } else {
150 button->SetIconImage(pIcon);
151 }
152 } else if (jsonObject.find("iconImage") != jsonEnd) {
153 auto resources = jsonObject.at("iconImage");
154 auto pIcon = AnsImageUtil::UnPackImage(resources);
155 if (pIcon == nullptr) {
156 ANS_LOGE("null pIcon");
157 delete button;
158 button = nullptr;
159 } else {
160 button->SetIconImage(pIcon);
161 }
162 }
163 return button;
164 }
165
ResourceFromJson(const nlohmann::json & resource,std::shared_ptr<ResourceManager::Resource> & resourceObj)166 bool NotificationIconButton::ResourceFromJson(const nlohmann::json &resource,
167 std::shared_ptr<ResourceManager::Resource>& resourceObj)
168 {
169 const auto &jsonEnd = resource.cend();
170 int resourceCount = BUTTON_RESOURCE_SIZE;
171 if (resource.find("bundleName") != jsonEnd && resource.at("bundleName").is_string()) {
172 resourceCount--;
173 resourceObj->bundleName = resource.at("bundleName").get<std::string>();
174 }
175 if (resource.find("moduleName") != jsonEnd && resource.at("moduleName").is_string()) {
176 resourceCount--;
177 resourceObj->moduleName = resource.at("moduleName").get<std::string>();
178 }
179 if (resource.find("id") != jsonEnd && resource.at("id").is_number_integer()) {
180 resourceCount--;
181 resourceObj->id = static_cast<uint32_t>(resource.at("id").get<int32_t>());
182 }
183 if (resourceCount == 0) {
184 return true;
185 }
186 ANS_LOGE("Resource from json failed.");
187 return false;
188 }
189
Marshalling(Parcel & parcel) const190 bool NotificationIconButton::Marshalling(Parcel &parcel) const
191 {
192 if (!parcel.WriteString(text_)) {
193 ANS_LOGE("Failed to write text");
194 return false;
195 }
196
197 if (!parcel.WriteString(name_)) {
198 ANS_LOGE("Failed to write name");
199 return false;
200 }
201
202 if (!parcel.WriteBool(hidePanel_)) {
203 ANS_LOGE("Failed to write hidePanel");
204 return false;
205 }
206
207 if (!WriteIconToParcel(parcel)) {
208 return false;
209 }
210
211 return true;
212 }
213
Unmarshalling(Parcel & parcel)214 NotificationIconButton *NotificationIconButton::Unmarshalling(Parcel &parcel)
215 {
216 NotificationIconButton *button = new (std::nothrow) NotificationIconButton();
217
218 if (button && !button->ReadFromParcel(parcel)) {
219 delete button;
220 button = nullptr;
221 }
222 return button;
223 }
224
ReadFromParcel(Parcel & parcel)225 bool NotificationIconButton::ReadFromParcel(Parcel &parcel)
226 {
227 if (!parcel.ReadString(text_)) {
228 ANS_LOGE("Failed to read text");
229 return false;
230 }
231
232 if (!parcel.ReadString(name_)) {
233 ANS_LOGE("Failed to read name");
234 return false;
235 }
236
237 if (!parcel.ReadBool(hidePanel_)) {
238 ANS_LOGE("Failed to read hidePanel");
239 return false;
240 }
241
242 bool valid {false};
243 valid = parcel.ReadBool();
244 if (valid) {
245 iconImage_ = std::shared_ptr<Media::PixelMap>(parcel.ReadParcelable<Media::PixelMap>());
246 if (!iconImage_) {
247 ANS_LOGE("Failed to read button icon.");
248 return false;
249 }
250 }
251
252 valid = parcel.ReadBool();
253 if (valid) {
254 if (!ReadResourceFromParcel(parcel, iconResource_)) {
255 ANS_LOGE("Failed to read button icon resource.");
256 return false;
257 }
258 }
259 return true;
260 }
261
WriteIconToParcel(Parcel & parcel) const262 bool NotificationIconButton::WriteIconToParcel(Parcel &parcel) const
263 {
264 bool valid {false};
265 valid = iconImage_ ? true : false;
266 if (!parcel.WriteBool(valid)) {
267 ANS_LOGE("Failed to write the flag which indicate whether button icon is null");
268 return false;
269 }
270 if (valid) {
271 if (!parcel.WriteParcelable(iconImage_.get())) {
272 ANS_LOGE("Failed to write iconImage.");
273 return false;
274 }
275 }
276
277 valid = iconResource_ ? true : false;
278 if (!parcel.WriteBool(valid)) {
279 ANS_LOGE("Failed to write the flag which indicate whether button icon resource is null");
280 return false;
281 }
282 if (valid) {
283 std::vector<std::string> iconResource = {};
284 iconResource.push_back(iconResource_->bundleName);
285 iconResource.push_back(iconResource_->moduleName);
286 iconResource.push_back(std::to_string(iconResource_->id));
287 if (!parcel.WriteStringVector(iconResource)) {
288 ANS_LOGE("Failed to write button icon resource");
289 return false;
290 }
291 }
292 return true;
293 }
294
ReadResourceFromParcel(Parcel & parcel,std::shared_ptr<ResourceManager::Resource> & resourceObj)295 bool NotificationIconButton::ReadResourceFromParcel(Parcel &parcel,
296 std::shared_ptr<ResourceManager::Resource> &resourceObj)
297 {
298 std::vector<std::string> iconsResource = {};
299 if (!parcel.ReadStringVector(&iconsResource)) {
300 ANS_LOGE("Failed to read button names");
301 return false;
302 }
303 if (iconsResource.size() < BUTTON_RESOURCE_SIZE) {
304 ANS_LOGE("Invalid input for button icons resource");
305 return false;
306 }
307 auto resource = std::make_shared<ResourceManager::Resource>();
308 resource->bundleName = iconsResource[RESOURCE_BUNDLENAME_INDEX];
309 resource->moduleName = iconsResource[RESOURCE_MODULENAME_INDEX];
310 std::stringstream sin(iconsResource[RESOURCE_ID_INDEX]);
311 int32_t checknum;
312 if (!(sin >> checknum)) {
313 ANS_LOGE("Invalid input for button icons resource");
314 return false;
315 }
316 resource->id = atoi(iconsResource[RESOURCE_ID_INDEX].c_str());
317 resourceObj = resource;
318 return true;
319 }
320 }
321 }
322