1 /*
2  * Copyright (c) 2021-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_local_live_view_content.h"
17 
18 #include <cstdint>
19 #include <string>                            // for basic_string, operator+
20 #include <algorithm>                         // for min
21 #include <vector>
22 
23 #include "ans_log_wrapper.h"
24 #include "nlohmann/json.hpp"                 // for json, basic_json<>::obje...
25 #include "notification_action_button.h"
26 #include "notification_basic_content.h"      // for NotificationBasicContent
27 #include "notification_capsule.h"
28 #include "notification_content.h"
29 #include "notification_json_convert.h"
30 #include "notification_progress.h"
31 #include "notification_local_live_view_button.h"
32 #include "notification_time.h"
33 #include "parcel.h"                          // for Parcel
34 
35 namespace OHOS {
36 namespace Notification {
37 
SetType(int32_t type)38 void NotificationLocalLiveViewContent::SetType(int32_t type)
39 {
40     type_ = type;
41 }
42 
GetType()43 int32_t NotificationLocalLiveViewContent::GetType()
44 {
45     return type_;
46 }
47 
SetCapsule(NotificationCapsule capsule)48 void NotificationLocalLiveViewContent::SetCapsule(NotificationCapsule capsule)
49 {
50     capsule_ = capsule;
51 }
52 
GetCapsule()53 NotificationCapsule NotificationLocalLiveViewContent::GetCapsule()
54 {
55     return capsule_;
56 }
57 
SetButton(NotificationLocalLiveViewButton button)58 void NotificationLocalLiveViewContent::SetButton(NotificationLocalLiveViewButton button)
59 {
60     button_ = button;
61 }
62 
GetButton()63 NotificationLocalLiveViewButton NotificationLocalLiveViewContent::GetButton()
64 {
65     return button_;
66 }
67 
SetProgress(NotificationProgress progress)68 void NotificationLocalLiveViewContent::SetProgress(NotificationProgress progress)
69 {
70     progress_ = progress;
71 }
72 
GetProgress()73 NotificationProgress NotificationLocalLiveViewContent::GetProgress()
74 {
75     return progress_;
76 }
77 
SetTime(NotificationTime time)78 void NotificationLocalLiveViewContent::SetTime(NotificationTime time)
79 {
80     time_ = time;
81 }
82 
GetTime()83 NotificationTime NotificationLocalLiveViewContent::GetTime()
84 {
85     return time_;
86 }
87 
addFlag(int32_t flag)88 void NotificationLocalLiveViewContent::addFlag(int32_t flag)
89 {
90     flags_.emplace_back(flag);
91 }
92 
isFlagExist(int32_t flag)93 bool NotificationLocalLiveViewContent::isFlagExist(int32_t flag)
94 {
95     auto it = std::find(flags_.begin(), flags_.end(), flag);
96     if (it != flags_.end()) {
97         return true;
98     } else {
99         return false;
100     }
101 }
102 
Dump()103 std::string NotificationLocalLiveViewContent::Dump()
104 {
105     return "NotificationLocalLiveViewContent{ " + NotificationBasicContent::Dump() +
106             ", type = " + std::to_string(type_) +
107             ", capsule = " + capsule_.Dump() +
108             ", button = " + button_.Dump() +
109             ", progress = " + progress_.Dump() +
110             ", time = " + time_.Dump() +
111             " }";
112 }
113 
ToJson(nlohmann::json & jsonObject) const114 bool NotificationLocalLiveViewContent::ToJson(nlohmann::json &jsonObject) const
115 {
116     if (!NotificationBasicContent::ToJson(jsonObject)) {
117         ANS_LOGE("Cannot convert basicContent to JSON");
118         return false;
119     }
120 
121     nlohmann::json capsuleObj;
122     if (!NotificationJsonConverter::ConvertToJson(&capsule_, capsuleObj)) {
123         ANS_LOGE("Cannot convert capsule to JSON");
124         return false;
125     }
126 
127     nlohmann::json buttonObj;
128     if (!NotificationJsonConverter::ConvertToJson(&button_, buttonObj)) {
129         ANS_LOGE("Cannot convert button to JSON");
130         return false;
131     }
132 
133     nlohmann::json progressObj;
134     if (!NotificationJsonConverter::ConvertToJson(&progress_, progressObj)) {
135         ANS_LOGE("Cannot convert progress to JSON");
136         return false;
137     }
138 
139     nlohmann::json timeObj;
140     if (!NotificationJsonConverter::ConvertToJson(&time_, timeObj)) {
141         ANS_LOGE("Cannot convert time to JSON");
142         return false;
143     }
144 
145     jsonObject["type"] = type_;
146     jsonObject["capsule"] = capsuleObj;
147     jsonObject["button"] = buttonObj;
148     jsonObject["progress"] = progressObj;
149     jsonObject["time"] = timeObj;
150     jsonObject["flags"] = nlohmann::json(flags_);
151 
152     return true;
153 }
154 
FromJson(const nlohmann::json & jsonObject)155 NotificationLocalLiveViewContent *NotificationLocalLiveViewContent::FromJson(const nlohmann::json &jsonObject)
156 {
157     if (jsonObject.is_null() or !jsonObject.is_object()) {
158         ANS_LOGE("Invalid JSON object");
159         return nullptr;
160     }
161 
162     auto pContent = new (std::nothrow) NotificationLocalLiveViewContent();
163     if (pContent == nullptr) {
164         ANS_LOGE("Failed to create localLiveViewContent instance");
165         return nullptr;
166     }
167 
168     pContent->ReadFromJson(jsonObject);
169 
170     const auto &jsonEnd = jsonObject.cend();
171     if (jsonObject.find("typeCode") != jsonEnd && jsonObject.at("typeCode").is_number_integer()) {
172         pContent->type_ = jsonObject.at("typeCode").get<int32_t>();
173     }
174 
175     if (jsonObject.find("capsule") != jsonEnd) {
176         auto capsuleObj = jsonObject.at("capsule");
177         auto pCapsule = NotificationJsonConverter::ConvertFromJson<NotificationCapsule>(capsuleObj);
178         if (pCapsule != nullptr) {
179             pContent->capsule_ = *pCapsule;
180             delete pCapsule;
181             pCapsule = nullptr;
182         }
183     }
184 
185     if (jsonObject.find("button") != jsonEnd) {
186         auto buttonObj = jsonObject.at("button");
187         auto pButton = NotificationJsonConverter::ConvertFromJson<NotificationLocalLiveViewButton>(buttonObj);
188         if (pButton != nullptr) {
189             pContent->button_ = *pButton;
190             delete pButton;
191             pButton = nullptr;
192         }
193     }
194 
195     if (jsonObject.find("progress") != jsonEnd) {
196         auto progressObj = jsonObject.at("progress");
197         auto pProgress = NotificationJsonConverter::ConvertFromJson<NotificationProgress>(progressObj);
198         if (pProgress != nullptr) {
199             pContent->progress_ = *pProgress;
200             delete pProgress;
201             pProgress = nullptr;
202         }
203     }
204 
205     if (jsonObject.find("time") != jsonEnd) {
206         auto timeObj = jsonObject.at("time");
207         auto pTime = NotificationJsonConverter::ConvertFromJson<NotificationTime>(timeObj);
208         if (pTime != nullptr) {
209             pContent->time_ = *pTime;
210             delete pTime;
211             pTime = nullptr;
212         }
213     }
214 
215     if (jsonObject.find("flags") != jsonEnd && jsonObject.at("flags").is_array()) {
216         pContent->flags_ = jsonObject.at("flags").get<std::vector<int32_t>>();
217     }
218 
219     return pContent;
220 }
221 
Marshalling(Parcel & parcel) const222 bool NotificationLocalLiveViewContent::Marshalling(Parcel &parcel) const
223 {
224     if (!NotificationBasicContent::Marshalling(parcel)) {
225         ANS_LOGE("Failed to write basic");
226         return false;
227     }
228 
229     if (contentType_ == static_cast<int32_t>(NotificationContent::Type::BASIC_TEXT)) {
230         return true;
231     }
232 
233     if (!parcel.WriteInt32(type_)) {
234         ANS_LOGE("Write type fail.");
235         return false;
236     }
237 
238     if (!parcel.WriteParcelable(&capsule_)) {
239         ANS_LOGE("Failed to write capsule");
240         return false;
241     }
242 
243     if (!parcel.WriteParcelable(&button_)) {
244         ANS_LOGE("Failed to write button");
245         return false;
246     }
247 
248     if (!parcel.WriteParcelable(&progress_)) {
249         ANS_LOGE("Failed to write progress");
250         return false;
251     }
252 
253     if (!parcel.WriteParcelable(&time_)) {
254         ANS_LOGE("Failed to write time");
255         return false;
256     }
257 
258     if (!parcel.WriteInt32Vector(flags_)) {
259         ANS_LOGE("Failed to write flags");
260         return false;
261     }
262 
263     return true;
264 }
265 
Unmarshalling(Parcel & parcel)266 NotificationLocalLiveViewContent *NotificationLocalLiveViewContent::Unmarshalling(Parcel &parcel)
267 {
268     auto pContent = new (std::nothrow) NotificationLocalLiveViewContent();
269     if ((pContent != nullptr) && !pContent->ReadFromParcel(parcel)) {
270         delete pContent;
271         pContent = nullptr;
272     }
273 
274     return pContent;
275 }
276 
ReadFromParcel(Parcel & parcel)277 bool NotificationLocalLiveViewContent::ReadFromParcel(Parcel &parcel)
278 {
279     if (!NotificationBasicContent::ReadFromParcel(parcel)) {
280         ANS_LOGE("Failed to read basic");
281         return false;
282     }
283 
284     if (!parcel.ReadInt32(type_)) {
285         ANS_LOGE("Read type failed.");
286         return false;
287     }
288 
289     auto pCapsule = parcel.ReadParcelable<NotificationCapsule>();
290     if (pCapsule == nullptr) {
291         ANS_LOGE("Failed to read capsule");
292         return false;
293     }
294     capsule_ = *pCapsule;
295     delete pCapsule;
296     pCapsule = nullptr;
297 
298     auto pButton = parcel.ReadParcelable<NotificationLocalLiveViewButton>();
299     if (pButton == nullptr) {
300         ANS_LOGE("Failed to read button");
301         return false;
302     }
303     button_ = *pButton;
304     delete pButton;
305     pButton = nullptr;
306 
307     auto pProgress = parcel.ReadParcelable<NotificationProgress>();
308     if (pProgress == nullptr) {
309         ANS_LOGE("Failed to read progress");
310         return false;
311     }
312     progress_ = *pProgress;
313     delete pProgress;
314     pProgress = nullptr;
315 
316     auto pTime = parcel.ReadParcelable<NotificationTime>();
317     if (pTime == nullptr) {
318         ANS_LOGE("Failed to read time");
319         return false;
320     }
321     time_ = *pTime;
322     delete pTime;
323     pTime = nullptr;
324 
325     if (!parcel.ReadInt32Vector(&flags_)) {
326         ANS_LOGE("Failed to read flags");
327         return false;
328     }
329 
330     return true;
331 }
332 
ClearButton()333 void NotificationLocalLiveViewContent::ClearButton()
334 {
335     button_.ClearButtonIcons();
336     button_.ClearButtonIconsResource();
337 }
338 
ClearCapsuleIcon()339 void NotificationLocalLiveViewContent::ClearCapsuleIcon()
340 {
341     capsule_.ResetIcon();
342 }
343 }  // namespace Notification
344 }  // namespace OHOS
345