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_conversational_content.h"
17
18 #include "ans_const_define.h"
19 #include "ans_log_wrapper.h"
20
21 namespace OHOS {
22 namespace Notification {
NotificationConversationalContent(const MessageUser & messageUser)23 NotificationConversationalContent::NotificationConversationalContent(const MessageUser &messageUser)
24 : messageUser_(messageUser)
25 {}
26
GetMessageUser() const27 MessageUser NotificationConversationalContent::GetMessageUser() const
28 {
29 return messageUser_;
30 }
31
SetConversationTitle(const std::string & conversationTitle)32 void NotificationConversationalContent::SetConversationTitle(const std::string &conversationTitle)
33 {
34 conversationTitle_ = conversationTitle;
35 }
36
GetConversationTitle() const37 std::string NotificationConversationalContent::GetConversationTitle() const
38 {
39 return conversationTitle_;
40 }
41
IsConversationGroup() const42 bool NotificationConversationalContent::IsConversationGroup() const
43 {
44 return isGroup_;
45 }
46
SetConversationGroup(bool isGroup)47 void NotificationConversationalContent::SetConversationGroup(bool isGroup)
48 {
49 isGroup_ = isGroup;
50 }
51
AddConversationalMessage(const std::string & text,int64_t timestamp,const MessageUser & sender)52 void NotificationConversationalContent::AddConversationalMessage(
53 const std::string &text, int64_t timestamp, const MessageUser &sender)
54 {
55 auto message = std::make_shared<NotificationConversationalMessage>(text, timestamp, sender);
56 if (!message) {
57 ANS_LOGE("Failed to create message");
58 return;
59 }
60
61 messages_.emplace_back(message);
62 }
63
AddConversationalMessage(const MessagePtr & message)64 void NotificationConversationalContent::AddConversationalMessage(const MessagePtr &message)
65 {
66 if (!message) {
67 ANS_LOGE("Message can not be null");
68 return;
69 }
70
71 messages_.emplace_back(message);
72 }
73
GetAllConversationalMessages() const74 NotificationConversationalContent::MessageVector NotificationConversationalContent::GetAllConversationalMessages() const
75 {
76 return messages_;
77 }
78
Dump()79 std::string NotificationConversationalContent::Dump()
80 {
81 std::string messages = "";
82 for (auto &message : messages_) {
83 if (!message) {
84 messages += "nullptr, ";
85 continue;
86 }
87 messages += message->Dump();
88 messages += ", ";
89 }
90 return "NotificationConversationalContent{ " + NotificationBasicContent::Dump() +
91 ", conversationTitle = " + conversationTitle_ +
92 ", isGroup = " + (isGroup_ ? "true" : "false") +
93 ", messageUser = " + messageUser_.Dump() +
94 ", messages = " + messages +
95 " }";
96 }
97
ToJson(nlohmann::json & jsonObject) const98 bool NotificationConversationalContent::ToJson(nlohmann::json &jsonObject) const
99 {
100 if (!NotificationBasicContent::ToJson(jsonObject)) {
101 ANS_LOGE("Cannot convert basicContent to JSON");
102 return false;
103 }
104
105 nlohmann::json userObj;
106 if (!NotificationJsonConverter::ConvertToJson(&messageUser_, userObj)) {
107 ANS_LOGE("Cannot convert messageUser to JSON");
108 return false;
109 }
110 jsonObject["messageUser"] = userObj;
111
112 jsonObject["conversationTitle"] = conversationTitle_;
113 jsonObject["isGroup"] = isGroup_;
114
115 nlohmann::json msgsArr = nlohmann::json::array();
116 for (auto &msg : messages_) {
117 if (!msg) {
118 continue;
119 }
120
121 nlohmann::json msgObj;
122 if (!NotificationJsonConverter::ConvertToJson(msg.get(), msgObj)) {
123 ANS_LOGE("Cannot convert conversationalMessage to JSON");
124 return false;
125 }
126 msgsArr.emplace_back(msgObj);
127 }
128 jsonObject["messages"] = msgsArr;
129
130 return true;
131 }
132
FromJson(const nlohmann::json & jsonObject)133 NotificationConversationalContent *NotificationConversationalContent::FromJson(const nlohmann::json &jsonObject)
134 {
135 if (jsonObject.is_null() or !jsonObject.is_object()) {
136 ANS_LOGE("Invalid JSON object");
137 return nullptr;
138 }
139
140 auto pContent = new (std::nothrow) NotificationConversationalContent();
141 if (pContent == nullptr) {
142 ANS_LOGE("Failed to create conversationalContent instance");
143 return nullptr;
144 }
145
146 pContent->ReadFromJson(jsonObject);
147
148 const auto &jsonEnd = jsonObject.cend();
149 if (jsonObject.find("messageUser") != jsonEnd) {
150 auto userObj = jsonObject.at("messageUser");
151 auto pUser = NotificationJsonConverter::ConvertFromJson<MessageUser>(userObj);
152 if (pUser != nullptr) {
153 pContent->messageUser_ = *pUser;
154
155 delete pUser;
156 pUser = nullptr;
157 }
158 }
159
160 if (jsonObject.find("messages") != jsonEnd) {
161 nlohmann::json msgsArr = jsonObject.at("messages");
162 for (auto &msgObj : msgsArr) {
163 auto pMsg = NotificationJsonConverter::ConvertFromJson<NotificationConversationalMessage>(msgObj);
164 if (pMsg == nullptr) {
165 ANS_LOGE("Failed to parse message ");
166
167 delete pContent;
168 pContent = nullptr;
169 return nullptr;
170 }
171
172 pContent->messages_.emplace_back(pMsg);
173 }
174 }
175
176 return pContent;
177 }
178
Marshalling(Parcel & parcel) const179 bool NotificationConversationalContent::Marshalling(Parcel &parcel) const
180 {
181 if (!NotificationBasicContent::Marshalling(parcel)) {
182 ANS_LOGE("Failed to write basic");
183 return false;
184 }
185
186 if (!parcel.WriteString(conversationTitle_)) {
187 ANS_LOGE("Failed to write conversation title");
188 return false;
189 }
190
191 if (!parcel.WriteBool(isGroup_)) {
192 ANS_LOGE("Failed to write flag group");
193 return false;
194 }
195
196 if (!parcel.WriteParcelable(&messageUser_)) {
197 ANS_LOGE("Failed to write messageUser");
198 return false;
199 }
200
201 if (!parcel.WriteUint64(messages_.size())) {
202 ANS_LOGE("Failed to write the size of messages");
203 return false;
204 }
205
206 for (auto it = messages_.begin(); it != messages_.end(); ++it) {
207 auto valid = (*it) ? true : false;
208 if (!parcel.WriteBool(valid)) {
209 ANS_LOGE("Failed to write the flag which indicate whether message is null");
210 return false;
211 }
212
213 if (!valid) {
214 ANS_LOGE("Invalid message, write to parcel failed");
215 return false;
216 }
217
218 if (!parcel.WriteParcelable(it->get())) {
219 ANS_LOGE("Failed to write message");
220 return false;
221 }
222 }
223
224 return true;
225 }
226
Unmarshalling(Parcel & parcel)227 NotificationConversationalContent *NotificationConversationalContent::Unmarshalling(Parcel &parcel)
228 {
229 auto pContent = new (std::nothrow) NotificationConversationalContent();
230 if ((pContent != nullptr) && !pContent->ReadFromParcel(parcel)) {
231 delete pContent;
232 pContent = nullptr;
233 }
234
235 return pContent;
236 }
237
ReadFromParcel(Parcel & parcel)238 bool NotificationConversationalContent::ReadFromParcel(Parcel &parcel)
239 {
240 if (!NotificationBasicContent::ReadFromParcel(parcel)) {
241 ANS_LOGE("Failed to read basic");
242 return false;
243 }
244
245 if (!parcel.ReadString(conversationTitle_)) {
246 ANS_LOGE("Failed to read conversation title");
247 return false;
248 }
249
250 isGroup_ = parcel.ReadBool();
251
252 auto pUser = parcel.ReadParcelable<MessageUser>();
253 if (pUser == nullptr) {
254 ANS_LOGE("Failed to read messageUser");
255 return false;
256 }
257 messageUser_ = *pUser;
258 delete pUser;
259 pUser = nullptr;
260
261 auto vsize = parcel.ReadUint64();
262 vsize = (vsize < MAX_CONVERSATIONAL_NUM) ? vsize : MAX_CONVERSATIONAL_NUM;
263 for (uint64_t it = 0; it < vsize; ++it) {
264 auto valid = parcel.ReadBool();
265 if (!valid) {
266 ANS_LOGE("Invalid message, read from parcel failed");
267 return false;
268 }
269
270 auto member = std::shared_ptr<NotificationConversationalMessage>(
271 parcel.ReadParcelable<NotificationConversationalMessage>());
272 if (member == nullptr) {
273 ANS_LOGE("Failed to read message");
274 messages_.clear();
275 return false;
276 }
277
278 messages_.emplace_back(member);
279 }
280
281 return true;
282 }
283 } // namespace Notification
284 } // namespace OHOS
285