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