1 /*
2 * Copyright (c) 2023 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_content.h"
17 #include "ans_log_wrapper.h"
18 #include "notification_local_live_view_content.h"
19
20 namespace OHOS {
21 namespace Notification {
NotificationContent(const std::shared_ptr<NotificationNormalContent> & normalContent)22 NotificationContent::NotificationContent(const std::shared_ptr<NotificationNormalContent> &normalContent)
23 {
24 if (!normalContent) {
25 ANS_LOGE("NotificationNormalContent can not be null");
26 return;
27 }
28
29 contentType_ = NotificationContent::Type::BASIC_TEXT;
30 content_ = normalContent;
31 }
32
NotificationContent(const std::shared_ptr<NotificationLongTextContent> & longTextContent)33 NotificationContent::NotificationContent(const std::shared_ptr<NotificationLongTextContent> &longTextContent)
34 {
35 if (!longTextContent) {
36 ANS_LOGE("NotificationLongTextContent can not be null");
37 return;
38 }
39
40 contentType_ = NotificationContent::Type::LONG_TEXT;
41 content_ = longTextContent;
42 }
43
NotificationContent(const std::shared_ptr<NotificationPictureContent> & pictureContent)44 NotificationContent::NotificationContent(const std::shared_ptr<NotificationPictureContent> &pictureContent)
45 {
46 if (!pictureContent) {
47 ANS_LOGE("NotificationPictureContent can not be null");
48 return;
49 }
50
51 contentType_ = NotificationContent::Type::PICTURE;
52 content_ = pictureContent;
53 }
54
NotificationContent(const std::shared_ptr<NotificationConversationalContent> & conversationContent)55 NotificationContent::NotificationContent(const std::shared_ptr<NotificationConversationalContent> &conversationContent)
56 {
57 if (!conversationContent) {
58 ANS_LOGE("NotificationConversationalContent can not be null");
59 return;
60 }
61
62 contentType_ = NotificationContent::Type::CONVERSATION;
63 content_ = conversationContent;
64 }
65
NotificationContent(const std::shared_ptr<NotificationMultiLineContent> & multiLineContent)66 NotificationContent::NotificationContent(const std::shared_ptr<NotificationMultiLineContent> &multiLineContent)
67 {
68 if (!multiLineContent) {
69 ANS_LOGE("NotificationMultiLineContent can not be null");
70 return;
71 }
72
73 contentType_ = NotificationContent::Type::MULTILINE;
74 content_ = multiLineContent;
75 }
76
NotificationContent(const std::shared_ptr<NotificationMediaContent> & mediaContent)77 NotificationContent::NotificationContent(const std::shared_ptr<NotificationMediaContent> &mediaContent)
78 {
79 if (!mediaContent) {
80 ANS_LOGE("NotificationMediaContent can not be null");
81 return;
82 }
83
84 contentType_ = NotificationContent::Type::MEDIA;
85 content_ = mediaContent;
86 }
87
NotificationContent(const std::shared_ptr<NotificationLocalLiveViewContent> & localLiveViewContent)88 NotificationContent::NotificationContent(const std::shared_ptr<NotificationLocalLiveViewContent> &localLiveViewContent)
89 {
90 if (!localLiveViewContent) {
91 ANS_LOGE("NotificationLocalLiveViewContent can not be null");
92 return;
93 }
94
95 contentType_ = NotificationContent::Type::LOCAL_LIVE_VIEW;
96 content_ = localLiveViewContent;
97 }
98
NotificationContent(const std::shared_ptr<NotificationLiveViewContent> & liveViewContent)99 NotificationContent::NotificationContent(const std::shared_ptr<NotificationLiveViewContent> &liveViewContent)
100 {
101 if (!liveViewContent) {
102 ANS_LOGE("NotificationLiveViewContent can not be null");
103 return;
104 }
105
106 contentType_ = NotificationContent::Type::LIVE_VIEW;
107 content_ = liveViewContent;
108 }
109
~NotificationContent()110 NotificationContent::~NotificationContent()
111 {}
112
GetContentType() const113 NotificationContent::Type NotificationContent::GetContentType() const
114 {
115 return contentType_;
116 }
117
GetNotificationContent() const118 std::shared_ptr<NotificationBasicContent> NotificationContent::GetNotificationContent() const
119 {
120 return content_;
121 }
122
Dump()123 std::string NotificationContent::Dump()
124 {
125 std::string contentTypeStr = (contentType_ == NotificationContent::Type::BASIC_TEXT) ? "BASIC_TEXT"
126 : (contentType_ == NotificationContent::Type::CONVERSATION) ? "CONVERSATION"
127 : (contentType_ == NotificationContent::Type::LONG_TEXT) ? "LONG_TEXT"
128 : (contentType_ == NotificationContent::Type::MEDIA) ? "MEDIA"
129 : (contentType_ == NotificationContent::Type::MULTILINE) ? "MULTILINE"
130 : (contentType_ == NotificationContent::Type::PICTURE) ? "PICTURE"
131 : (contentType_ == NotificationContent::Type::LOCAL_LIVE_VIEW) ? "LOCAL_LIVE_VIEW"
132 : (contentType_ == NotificationContent::Type::LIVE_VIEW) ? "LIVE_VIEW"
133 : "NONE";
134 return "NotificationContent{ "
135 "contentType = " + contentTypeStr +
136 ", content = " + (content_ ? content_->Dump() : "null") +
137 " }";
138 }
139
ToJson(nlohmann::json & jsonObject) const140 bool NotificationContent::ToJson(nlohmann::json &jsonObject) const
141 {
142 jsonObject["contentType"] = static_cast<int32_t>(contentType_);
143 jsonObject["notificationContentType"] = static_cast<int32_t>(contentType_);
144
145 if (!content_) {
146 ANS_LOGE("Invalid content. Cannot convert to JSON.");
147 return false;
148 }
149
150 nlohmann::json contentObj;
151 if (!NotificationJsonConverter::ConvertToJson(content_.get(), contentObj)) {
152 ANS_LOGE("Cannot convert content to JSON");
153 return false;
154 }
155 jsonObject["content"] = contentObj;
156
157 return true;
158 }
159
FromJson(const nlohmann::json & jsonObject)160 NotificationContent *NotificationContent::FromJson(const nlohmann::json &jsonObject)
161 {
162 if (jsonObject.is_null() or !jsonObject.is_object()) {
163 ANS_LOGE("Invalid JSON object");
164 return nullptr;
165 }
166 const auto &jsonEnd = jsonObject.cend();
167 if ((jsonObject.find("contentType") == jsonEnd) || (jsonObject.find("content") == jsonEnd)) {
168 ANS_LOGE("Incomplete NotificationContent json object. Cannot convert content from JSON.");
169 return nullptr;
170 }
171
172 auto pContent = new (std::nothrow) NotificationContent();
173 if (pContent == nullptr) {
174 ANS_LOGE("Failed to create NotificationContent instance");
175 return nullptr;
176 }
177
178 if (!ConvertJsonToContent(pContent, jsonObject)) {
179 delete pContent;
180 pContent = nullptr;
181 return nullptr;
182 }
183
184 return pContent;
185 }
186
Marshalling(Parcel & parcel) const187 bool NotificationContent::Marshalling(Parcel &parcel) const
188 {
189 if (!parcel.WriteInt32(static_cast<int32_t>(contentType_))) {
190 ANS_LOGE("Failed to write contentType");
191 return false;
192 }
193
194 auto valid = content_ ? true : false;
195 if (!parcel.WriteBool(valid)) {
196 ANS_LOGE("Failed to write the flag which indicate whether content is null");
197 return false;
198 }
199
200 if (valid) {
201 if (!parcel.WriteParcelable(content_.get())) {
202 ANS_LOGE("Failed to write content");
203 return false;
204 }
205 }
206
207 return true;
208 }
209
Unmarshalling(Parcel & parcel)210 NotificationContent *NotificationContent::Unmarshalling(Parcel &parcel)
211 {
212 auto pContent = new (std::nothrow) NotificationContent();
213 if ((pContent != nullptr) && !pContent->ReadFromParcel(parcel)) {
214 delete pContent;
215 pContent = nullptr;
216 }
217
218 return pContent;
219 }
220
ReadFromParcel(Parcel & parcel)221 bool NotificationContent::ReadFromParcel(Parcel &parcel)
222 {
223 contentType_ = static_cast<NotificationContent::Type>(parcel.ReadInt32());
224
225 if (!parcel.ReadBool()) {
226 return true;
227 }
228
229 switch (contentType_) {
230 case NotificationContent::Type::BASIC_TEXT:
231 content_ = std::static_pointer_cast<NotificationBasicContent>(
232 std::shared_ptr<NotificationNormalContent>(parcel.ReadParcelable<NotificationNormalContent>()));
233 break;
234 case NotificationContent::Type::CONVERSATION:
235 content_ =
236 std::static_pointer_cast<NotificationBasicContent>(std::shared_ptr<NotificationConversationalContent>(
237 parcel.ReadParcelable<NotificationConversationalContent>()));
238 break;
239 case NotificationContent::Type::LONG_TEXT:
240 content_ = std::static_pointer_cast<NotificationBasicContent>(
241 std::shared_ptr<NotificationLongTextContent>(parcel.ReadParcelable<NotificationLongTextContent>()));
242 break;
243 case NotificationContent::Type::MEDIA:
244 content_ = std::static_pointer_cast<NotificationBasicContent>(
245 std::shared_ptr<NotificationMediaContent>(parcel.ReadParcelable<NotificationMediaContent>()));
246 break;
247 case NotificationContent::Type::MULTILINE:
248 content_ = std::static_pointer_cast<NotificationBasicContent>(
249 std::shared_ptr<NotificationMultiLineContent>(parcel.ReadParcelable<NotificationMultiLineContent>()));
250 break;
251 case NotificationContent::Type::PICTURE:
252 content_ = std::static_pointer_cast<NotificationBasicContent>(
253 std::shared_ptr<NotificationPictureContent>(parcel.ReadParcelable<NotificationPictureContent>()));
254 break;
255 case NotificationContent::Type::LOCAL_LIVE_VIEW:
256 content_ = std::static_pointer_cast<NotificationBasicContent>(
257 std::shared_ptr<NotificationLocalLiveViewContent>(
258 parcel.ReadParcelable<NotificationLocalLiveViewContent>()));
259 break;
260 case NotificationContent::Type::LIVE_VIEW:
261 content_ = std::static_pointer_cast<NotificationBasicContent>(
262 std::shared_ptr<NotificationLiveViewContent>(parcel.ReadParcelable<NotificationLiveViewContent>()));
263 break;
264 default:
265 ANS_LOGE("Invalid contentType");
266 return false;
267 }
268 if (!content_) {
269 ANS_LOGE("Failed to read content");
270 return false;
271 }
272
273 return true;
274 }
275
ConvertJsonToContent(NotificationContent * target,const nlohmann::json & jsonObject)276 bool NotificationContent::ConvertJsonToContent(NotificationContent *target, const nlohmann::json &jsonObject)
277 {
278 if (target == nullptr) {
279 ANS_LOGE("Invalid input parameter");
280 return false;
281 }
282
283 auto contentType = jsonObject.at("contentType");
284 if (!contentType.is_number_integer()) {
285 ANS_LOGE("ContentType is not integer");
286 return false;
287 }
288 target->contentType_ = static_cast<NotificationContent::Type>(contentType.get<int32_t>());
289
290 auto contentObj = jsonObject.at("content");
291 if (contentObj.is_null()) {
292 ANS_LOGE("Invalid json object. Cannot convert content from JSON.");
293 return false;
294 }
295
296 NotificationBasicContent *pBasicContent {nullptr};
297 switch (target->contentType_) {
298 case NotificationContent::Type::BASIC_TEXT:
299 pBasicContent = NotificationJsonConverter::ConvertFromJson<NotificationNormalContent>(contentObj);
300 break;
301 case NotificationContent::Type::CONVERSATION:
302 pBasicContent = NotificationJsonConverter::ConvertFromJson<NotificationConversationalContent>(contentObj);
303 break;
304 case NotificationContent::Type::LONG_TEXT:
305 pBasicContent = NotificationJsonConverter::ConvertFromJson<NotificationLongTextContent>(contentObj);
306 break;
307 case NotificationContent::Type::MULTILINE:
308 pBasicContent = NotificationJsonConverter::ConvertFromJson<NotificationMultiLineContent>(contentObj);
309 break;
310 case NotificationContent::Type::PICTURE:
311 pBasicContent = NotificationJsonConverter::ConvertFromJson<NotificationPictureContent>(contentObj);
312 break;
313 case NotificationContent::Type::LOCAL_LIVE_VIEW:
314 pBasicContent = NotificationJsonConverter::ConvertFromJson<NotificationLocalLiveViewContent>(contentObj);
315 break;
316 case NotificationContent::Type::LIVE_VIEW:
317 pBasicContent = NotificationJsonConverter::ConvertFromJson<NotificationLiveViewContent>(contentObj);
318 break;
319 default:
320 ANS_LOGE("Invalid contentType");
321 break;
322 }
323 if (pBasicContent == nullptr) {
324 ANS_LOGE("Parse content error!");
325 return false;
326 }
327 target->content_ = std::shared_ptr<NotificationBasicContent>(pBasicContent);
328
329 return true;
330 }
331 } // namespace Notification
332 } // namespace OHOS
333