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_live_view_content.h"
17 #include <string>
18 #include "ans_image_util.h"
19 #include "ans_log_wrapper.h"
20 #include "want_params_wrapper.h"
21 #include "ans_const_define.h"
22 
23 namespace OHOS {
24 namespace Notification {
25 const uint32_t NotificationLiveViewContent::MAX_VERSION {0xffffffff};
SetLiveViewStatus(const LiveViewStatus status)26 void NotificationLiveViewContent::SetLiveViewStatus(const LiveViewStatus status)
27 {
28     liveViewStatus_ = status;
29 }
30 
GetLiveViewStatus() const31 NotificationLiveViewContent::LiveViewStatus NotificationLiveViewContent::GetLiveViewStatus() const
32 {
33     return liveViewStatus_;
34 }
35 
SetVersion(uint32_t version)36 void NotificationLiveViewContent::SetVersion(uint32_t version)
37 {
38     version_ = version;
39 }
40 
GetVersion() const41 uint32_t NotificationLiveViewContent::GetVersion() const
42 {
43     return version_;
44 }
45 
SetExtraInfo(const std::shared_ptr<AAFwk::WantParams> & extras)46 void NotificationLiveViewContent::SetExtraInfo(const std::shared_ptr<AAFwk::WantParams> &extras)
47 {
48     extraInfo_ = extras;
49 }
50 
GetExtraInfo() const51 std::shared_ptr<AAFwk::WantParams> NotificationLiveViewContent::GetExtraInfo() const
52 {
53     return extraInfo_;
54 }
55 
SetPicture(const PictureMap & pictureMap)56 void NotificationLiveViewContent::SetPicture(const PictureMap &pictureMap)
57 {
58     pictureMap_ = pictureMap;
59 }
60 
GetPicture() const61 PictureMap NotificationLiveViewContent::GetPicture() const
62 {
63     return pictureMap_;
64 }
65 
SetIsOnlyLocalUpdate(const bool & isOnlyLocalUpdate)66 void NotificationLiveViewContent::SetIsOnlyLocalUpdate(const bool &isOnlyLocalUpdate)
67 {
68     isOnlyLocalUpdate_ = isOnlyLocalUpdate;
69 }
70 
GetIsOnlyLocalUpdate() const71 bool NotificationLiveViewContent::GetIsOnlyLocalUpdate() const
72 {
73     return isOnlyLocalUpdate_;
74 }
75 
Dump()76 std::string NotificationLiveViewContent::Dump()
77 {
78     std::string extraStr{"null"};
79     if (extraInfo_ != nullptr) {
80         AAFwk::WantParamWrapper wWrapper(*extraInfo_);
81         extraStr = wWrapper.ToString();
82     }
83 
84     std::string pictureStr {", pictureMap = {"};
85     for (auto &picture : pictureMap_) {
86         pictureStr += " { key = " + picture.first + ", value = " +
87             (picture.second.empty() ? "empty" : "not empty") + " },";
88     }
89     if (pictureStr[pictureStr.length() - 1] == ',') {
90         pictureStr[pictureStr.length() - 1] = ' ';
91     }
92     pictureStr += "}";
93 
94     return "NotificationLiveViewContent{ " + NotificationBasicContent::Dump() +
95         ", status = " + std::to_string(static_cast<int32_t>(liveViewStatus_)) + ", version = " +
96         std::to_string(static_cast<int32_t>(version_)) + ", extraInfo = " + extraStr +
97         ", isOnlyLocalUpdate_ = " + (GetIsOnlyLocalUpdate()?"true":"false") + pictureStr + "}";
98 }
99 
PictureToJson(nlohmann::json & jsonObject) const100 bool NotificationLiveViewContent::PictureToJson(nlohmann::json &jsonObject) const
101 {
102     nlohmann::json pixelMap;
103 
104     if (pictureMap_.empty()) {
105         return true;
106     }
107     for (const auto &picture : pictureMap_) {
108         nlohmann::json pixelRecordArr = nlohmann::json::array();
109         for (const auto &pixelMap : picture.second) {
110             pixelRecordArr.emplace_back(AnsImageUtil::PackImage(pixelMap));
111         }
112         pixelMap[picture.first] = pixelRecordArr;
113     }
114     jsonObject["pictureMap"] = pixelMap;
115     return true;
116 }
117 
ToJson(nlohmann::json & jsonObject) const118 bool NotificationLiveViewContent::ToJson(nlohmann::json &jsonObject) const
119 {
120     if (!NotificationBasicContent::ToJson(jsonObject)) {
121         ANS_LOGE("Cannot convert basicContent to JSON");
122         return false;
123     }
124 
125     jsonObject["status"] = static_cast<int32_t>(liveViewStatus_);
126     jsonObject["version"] = version_;
127 
128     if (extraInfo_) {
129         AAFwk::WantParamWrapper wWrapper(*extraInfo_);
130         jsonObject["extraInfo"] = wWrapper.ToString();
131     }
132 
133     jsonObject["isLocalUpdateOnly"] = isOnlyLocalUpdate_;
134 
135     return PictureToJson(jsonObject);
136 }
137 
ConvertPictureFromJson(const nlohmann::json & jsonObject)138 void NotificationLiveViewContent::ConvertPictureFromJson(const nlohmann::json &jsonObject)
139 {
140     const auto &jsonEnd = jsonObject.cend();
141     if ((jsonObject.find("pictureMap") != jsonEnd) && jsonObject.at("pictureMap").is_object()) {
142         auto pictureMap = jsonObject.at("pictureMap").get<nlohmann::json>();
143         for (auto it = pictureMap.begin(); it != pictureMap.end(); it++) {
144             if (!it.value().is_array()) {
145                 continue;
146             }
147             auto pictureArray = it.value().get<std::vector<std::string>>();
148             pictureMap_[it.key()] = std::vector<std::shared_ptr<Media::PixelMap>>();
149             for (const auto &picture : pictureArray) {
150                 pictureMap_[it.key()].emplace_back(AnsImageUtil::UnPackImage(picture));
151             }
152         }
153     }
154 }
155 
FromJson(const nlohmann::json & jsonObject)156 NotificationLiveViewContent *NotificationLiveViewContent::FromJson(const nlohmann::json &jsonObject)
157 {
158     if (jsonObject.is_null() or !jsonObject.is_object()) {
159         ANS_LOGE("Invalid JSON object");
160         return nullptr;
161     }
162 
163     auto *pContent = new (std::nothrow) NotificationLiveViewContent();
164     if (pContent == nullptr) {
165         ANS_LOGE("Failed to create liveViewContent instance");
166         return nullptr;
167     }
168 
169     pContent->ReadFromJson(jsonObject);
170 
171     const auto &jsonEnd = jsonObject.cend();
172     if (jsonObject.find("status") != jsonEnd && jsonObject.at("status").is_number_integer()) {
173         auto statusValue = jsonObject.at("status").get<int32_t>();
174         pContent->liveViewStatus_ = static_cast<NotificationLiveViewContent::LiveViewStatus>(statusValue);
175     }
176 
177     if (jsonObject.find("version") != jsonEnd && jsonObject.at("version").is_number_integer()) {
178         pContent->version_ = jsonObject.at("version").get<uint32_t>();
179     }
180 
181     if (jsonObject.find("extraInfo") != jsonEnd && jsonObject.at("extraInfo").is_string()) {
182         std::string extraInfoStr = jsonObject.at("extraInfo").get<std::string>();
183         if (!extraInfoStr.empty()) {
184             AAFwk::WantParams params = AAFwk::WantParamWrapper::ParseWantParamsWithBrackets(extraInfoStr);
185             pContent->extraInfo_ = std::make_shared<AAFwk::WantParams>(params);
186         }
187     }
188     if (jsonObject.find("isOnlyLocalUpdate") != jsonEnd && jsonObject.at("isOnlyLocalUpdate").is_boolean()) {
189         pContent->isOnlyLocalUpdate_ = jsonObject.at("isOnlyLocalUpdate").get<bool>();
190     }
191     pContent->ConvertPictureFromJson(jsonObject);
192     return pContent;
193 }
194 
Marshalling(Parcel & parcel) const195 bool NotificationLiveViewContent::Marshalling(Parcel &parcel) const
196 {
197     if (!NotificationBasicContent::Marshalling(parcel)) {
198         ANS_LOGE("Failed to write basic");
199         return false;
200     }
201 
202     if (!parcel.WriteInt32(static_cast<int32_t>(liveViewStatus_))) {
203         ANS_LOGE("Failed to write liveView status");
204         return false;
205     }
206 
207     if (!parcel.WriteUint32(version_)) {
208         ANS_LOGE("Failed to write version");
209         return false;
210     }
211 
212     bool valid{false};
213     if (extraInfo_ != nullptr) {
214         valid = true;
215     }
216     if (!parcel.WriteBool(valid)) {
217         ANS_LOGE("Failed to write the flag which indicate whether extraInfo is null");
218         return false;
219     }
220     if (valid) {
221         if (!parcel.WriteParcelable(extraInfo_.get())) {
222             ANS_LOGE("Failed to write additionalParams");
223             return false;
224         }
225     }
226     if (!parcel.WriteBool(isOnlyLocalUpdate_)) {
227         ANS_LOGE("OnlyLocalUpdate is Failed to write.");
228         return false;
229     }
230     if (!parcel.WriteUint64(pictureMap_.size())) {
231         ANS_LOGE("Failed to write the size of pictureMap.");
232         return false;
233     }
234 
235     return MarshallingPictureMap(parcel);
236 }
237 
Unmarshalling(Parcel & parcel)238 NotificationLiveViewContent *NotificationLiveViewContent::Unmarshalling(Parcel &parcel)
239 {
240     auto *pContent = new (std::nothrow) NotificationLiveViewContent();
241     if ((pContent != nullptr) && !pContent->ReadFromParcel(parcel)) {
242         delete pContent;
243         pContent = nullptr;
244     }
245 
246     return pContent;
247 }
248 
ReadFromParcel(Parcel & parcel)249 bool NotificationLiveViewContent::ReadFromParcel(Parcel &parcel)
250 {
251     if (!NotificationBasicContent::ReadFromParcel(parcel)) {
252         ANS_LOGE("Failed to read basic");
253         return false;
254     }
255 
256     liveViewStatus_ = static_cast<NotificationLiveViewContent::LiveViewStatus>(parcel.ReadInt32());
257     version_ = parcel.ReadUint32();
258 
259     bool valid = parcel.ReadBool();
260     if (valid) {
261         extraInfo_ = std::shared_ptr<AAFwk::WantParams>(parcel.ReadParcelable<AAFwk::WantParams>());
262         if (!extraInfo_) {
263             ANS_LOGE("Failed to read extraInfo.");
264             return false;
265         }
266     }
267 
268     isOnlyLocalUpdate_ = parcel.ReadBool();
269 
270     uint64_t len = parcel.ReadUint64();
271     if (len > MAX_PARCELABLE_VECTOR_NUM) {
272         ANS_LOGE("Size exceeds the range.");
273         return false;
274     }
275     for (uint64_t i = 0; i < len; i++) {
276         auto key = parcel.ReadString();
277         std::vector<std::string> strVec;
278         if (!parcel.ReadStringVector(&strVec)) {
279             ANS_LOGE("Failed to read extraInfo vector string.");
280             return false;
281         }
282         std::vector<std::shared_ptr<Media::PixelMap>> pixelMapVec;
283         pixelMapVec.reserve(strVec.size());
284         for (const auto &str : strVec) {
285             pixelMapVec.emplace_back(AnsImageUtil::UnPackImage(str));
286         }
287         pictureMap_[key] = pixelMapVec;
288     }
289 
290     return true;
291 }
292 
MarshallingPictureMap(Parcel & parcel) const293 bool NotificationLiveViewContent::MarshallingPictureMap(Parcel &parcel) const
294 {
295     if (!pictureMarshallingMap_.empty()) {
296         ANS_LOGD("Write pictureMap by pictureMarshallingMap.");
297         for (const auto &picture : pictureMarshallingMap_) {
298             if (!parcel.WriteString(picture.first)) {
299                 ANS_LOGE("Failed to write picture map key %{public}s.", picture.first.c_str());
300                 return false;
301             }
302 
303             if (!parcel.WriteStringVector(picture.second)) {
304                 ANS_LOGE("Failed to write picture vector of key %{public}s.", picture.first.c_str());
305                 return false;
306             }
307         }
308         return true;
309     }
310 
311     if (!pictureMap_.empty()) {
312         for (const auto &picture : pictureMap_) {
313             if (!parcel.WriteString(picture.first)) {
314                 ANS_LOGE("Failed to write picture map key %{public}s.", picture.first.c_str());
315                 return false;
316             }
317             std::vector<std::string> pixelVec;
318             pixelVec.reserve(picture.second.size());
319             for (const auto &pixel : picture.second) {
320                 pixelVec.emplace_back(AnsImageUtil::PackImage(pixel));
321             }
322             if (!parcel.WriteStringVector(pixelVec)) {
323                 ANS_LOGE("Failed to write picture vector of key %{public}s.", picture.first.c_str());
324                 return false;
325             }
326         }
327     }
328 
329     return true;
330 }
331 
FillPictureMarshallingMap()332 void NotificationLiveViewContent::FillPictureMarshallingMap()
333 {
334     pictureMarshallingMap_.clear();
335     if (!pictureMap_.empty()) {
336         for (const auto &picture : pictureMap_) {
337             std::vector<std::string> pixelVec;
338             pixelVec.reserve(picture.second.size());
339             for (const auto &pixel : picture.second) {
340                 pixelVec.emplace_back(AnsImageUtil::PackImage(pixel));
341             }
342             pictureMarshallingMap_[picture.first] = pixelVec;
343         }
344     }
345 }
346 
ClearPictureMarshallingMap()347 void NotificationLiveViewContent::ClearPictureMarshallingMap()
348 {
349     pictureMarshallingMap_.clear();
350 }
351 
ClearPictureMap()352 void NotificationLiveViewContent::ClearPictureMap()
353 {
354     return pictureMap_.clear();
355 }
356 
GetPictureMarshallingMap() const357 PictureMarshallingMap NotificationLiveViewContent::GetPictureMarshallingMap() const
358 {
359     return pictureMarshallingMap_;
360 }
361 
362 }  // namespace Notification
363 }  // namespace OHOS
364