1 /*
2 * Copyright (c) 2021-2022 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_user_input.h"
17
18 #include "ans_log_wrapper.h"
19 #include "want_params_wrapper.h"
20
21 namespace OHOS {
22 namespace Notification {
SetInputsSource(AAFwk::Want & want,NotificationConstant::InputsSource source)23 void NotificationUserInput::SetInputsSource(AAFwk::Want &want, NotificationConstant::InputsSource source)
24 {
25 want.SetParam(NotificationConstant::EXTRA_INPUTS_SOURCE, static_cast<int32_t>(source));
26 }
27
GetInputsSource(const AAFwk::Want & want)28 NotificationConstant::InputsSource NotificationUserInput::GetInputsSource(const AAFwk::Want &want)
29 {
30 auto inputsSource = want.GetIntParam(NotificationConstant::EXTRA_INPUTS_SOURCE,
31 static_cast<int32_t>(NotificationConstant::InputsSource::FREE_FORM_INPUT));
32 return static_cast<NotificationConstant::InputsSource>(inputsSource);
33 }
34
AddInputsToWant(const std::vector<std::shared_ptr<NotificationUserInput>> & userInputs,AAFwk::Want & want,const AAFwk::WantParams & additional)35 void NotificationUserInput::AddInputsToWant(const std::vector<std::shared_ptr<NotificationUserInput>> &userInputs,
36 AAFwk::Want &want, const AAFwk::WantParams &additional)
37 {}
38
GetInputsFromWant(const AAFwk::Want & want)39 std::shared_ptr<AAFwk::WantParams> NotificationUserInput::GetInputsFromWant(const AAFwk::Want &want)
40 {
41 return {};
42 }
43
AddMimeInputToWant(const NotificationUserInput & userInput,AAFwk::Want & want,const std::map<std::string,std::shared_ptr<Uri>> & results)44 void NotificationUserInput::AddMimeInputToWant(const NotificationUserInput &userInput, AAFwk::Want &want,
45 const std::map<std::string, std::shared_ptr<Uri>> &results)
46 {}
47
GetMimeInputsFromWant(const AAFwk::Want & want,const std::string & inputKey)48 std::map<std::string, std::shared_ptr<Uri>> NotificationUserInput::GetMimeInputsFromWant(
49 const AAFwk::Want &want, const std::string &inputKey)
50 {
51 return {};
52 }
53
Create(const std::string & inputKey)54 std::shared_ptr<NotificationUserInput> NotificationUserInput::Create(const std::string &inputKey)
55 {
56 if (inputKey.empty()) {
57 ANS_LOGE("The param of inputKey is empty");
58 return {};
59 }
60
61 auto pUserInput = new (std::nothrow) NotificationUserInput(inputKey);
62 if (pUserInput == nullptr) {
63 ANS_LOGE("create NotificationUserInput object failed");
64 return {};
65 }
66
67 return std::shared_ptr<NotificationUserInput>(pUserInput);
68 }
69
Create(const std::string & inputKey,const std::string & tag,const std::vector<std::string> & options,bool permitFreeFormInput,const std::set<std::string> & permitMimeTypes,const std::shared_ptr<AAFwk::WantParams> & additional,NotificationConstant::InputEditType editType)70 std::shared_ptr<NotificationUserInput> NotificationUserInput::Create(const std::string &inputKey,
71 const std::string &tag, const std::vector<std::string> &options, bool permitFreeFormInput,
72 const std::set<std::string> &permitMimeTypes, const std::shared_ptr<AAFwk::WantParams> &additional,
73 NotificationConstant::InputEditType editType)
74 {
75 if (inputKey.empty()) {
76 ANS_LOGE("The param of inputKey is empty");
77 return {};
78 }
79
80 if (!permitFreeFormInput) {
81 if (editType == NotificationConstant::InputEditType::EDIT_ENABLED) {
82 ANS_LOGE("Setting editType to enable requires permitFreeFormInput to be set to true");
83 return {};
84 }
85
86 if (options.empty() && permitMimeTypes.empty()) {
87 ANS_LOGE("options and permitMimeTypes cannot be empty at the same time");
88 return {};
89 }
90 }
91
92 auto realAdditional = additional;
93 if (!realAdditional) {
94 realAdditional = std::make_shared<AAFwk::WantParams>();
95 }
96
97 auto pUserInput = new (std::nothrow)
98 NotificationUserInput(inputKey, tag, options, permitFreeFormInput, permitMimeTypes, realAdditional, editType);
99 if (pUserInput == nullptr) {
100 ANS_LOGE("create NotificationUserInput object failed");
101 return {};
102 }
103
104 return std::shared_ptr<NotificationUserInput>(pUserInput);
105 }
106
NotificationUserInput(const std::string & inputKey)107 NotificationUserInput::NotificationUserInput(const std::string &inputKey)
108 : inputKey_(inputKey), additionalData_(std::make_shared<AAFwk::WantParams>())
109 {}
110
NotificationUserInput(const std::string & inputKey,const std::string & tag,const std::vector<std::string> & options,bool permitFreeFormInput,const std::set<std::string> & permitMimeTypes,const std::shared_ptr<AAFwk::WantParams> & additional,NotificationConstant::InputEditType editType)111 NotificationUserInput::NotificationUserInput(const std::string &inputKey, const std::string &tag,
112 const std::vector<std::string> &options, bool permitFreeFormInput, const std::set<std::string> &permitMimeTypes,
113 const std::shared_ptr<AAFwk::WantParams> &additional, NotificationConstant::InputEditType editType)
114 : inputKey_(inputKey),
115 tag_(tag),
116 options_(options),
117 permitFreeFormInput_(permitFreeFormInput),
118 permitMimeTypes_(permitMimeTypes),
119 additionalData_(additional),
120 editType_(editType)
121 {}
122
GetInputKey() const123 std::string NotificationUserInput::GetInputKey() const
124 {
125 return inputKey_;
126 }
127
AddAdditionalData(AAFwk::WantParams & additional)128 void NotificationUserInput::AddAdditionalData(AAFwk::WantParams &additional)
129 {
130 if (additionalData_) {
131 *additionalData_ = additional;
132 }
133 }
134
GetAdditionalData() const135 const std::shared_ptr<AAFwk::WantParams> NotificationUserInput::GetAdditionalData() const
136 {
137 return additionalData_;
138 }
139
SetEditType(NotificationConstant::InputEditType inputEditType)140 void NotificationUserInput::SetEditType(NotificationConstant::InputEditType inputEditType)
141 {
142 editType_ = inputEditType;
143 }
144
GetEditType() const145 NotificationConstant::InputEditType NotificationUserInput::GetEditType() const
146 {
147 return editType_;
148 }
149
SetOptions(const std::vector<std::string> & options)150 void NotificationUserInput::SetOptions(const std::vector<std::string> &options)
151 {
152 options_ = options;
153 }
154
GetOptions() const155 std::vector<std::string> NotificationUserInput::GetOptions() const
156 {
157 return options_;
158 }
159
SetPermitMimeTypes(const std::string & mimeType,bool doPermit)160 void NotificationUserInput::SetPermitMimeTypes(const std::string &mimeType, bool doPermit)
161 {
162 if (mimeType.empty()) {
163 ANS_LOGE("The mimeType is invalid.");
164 return;
165 }
166
167 if (doPermit) {
168 permitMimeTypes_.emplace(mimeType);
169 return;
170 }
171
172 permitMimeTypes_.erase(mimeType);
173 }
174
GetPermitMimeTypes() const175 std::set<std::string> NotificationUserInput::GetPermitMimeTypes() const
176 {
177 return permitMimeTypes_;
178 }
179
IsMimeTypeOnly() const180 bool NotificationUserInput::IsMimeTypeOnly() const
181 {
182 return !permitFreeFormInput_ && options_.empty() && !permitMimeTypes_.empty();
183 }
184
SetTag(const std::string tag)185 void NotificationUserInput::SetTag(const std::string tag)
186 {
187 tag_ = tag;
188 }
189
GetTag() const190 std::string NotificationUserInput::GetTag() const
191 {
192 return tag_;
193 }
194
SetPermitFreeFormInput(bool permitFreeFormInput)195 void NotificationUserInput::SetPermitFreeFormInput(bool permitFreeFormInput)
196 {
197 permitFreeFormInput_ = permitFreeFormInput;
198 }
199
IsPermitFreeFormInput() const200 bool NotificationUserInput::IsPermitFreeFormInput() const
201 {
202 return permitFreeFormInput_;
203 }
204
Dump()205 std::string NotificationUserInput::Dump()
206 {
207 std::string options;
208 for (std::string option : options_) {
209 options += option + ", ";
210 }
211 options.pop_back();
212 options.pop_back();
213
214 std::string permitMimeTypes;
215 for (auto permitMimeType : permitMimeTypes_) {
216 permitMimeTypes += permitMimeType + ", ";
217 }
218 permitMimeTypes.pop_back();
219 permitMimeTypes.pop_back();
220
221 return "NotificationUserInput{ "
222 "inputKey = " + inputKey_ +
223 ", tag = " + tag_ +
224 ", options = [" + options + "]" +
225 ", permitFreeFormInput = " + (permitFreeFormInput_ ? "true" : "false") +
226 ", permitMimeTypes = [" + permitMimeTypes + "]" +
227 ", editType = " + std::to_string(static_cast<int32_t>(editType_)) +
228 " }";
229 }
230
ToJson(nlohmann::json & jsonObject) const231 bool NotificationUserInput::ToJson(nlohmann::json &jsonObject) const
232 {
233 jsonObject["inputKey"] = inputKey_;
234 jsonObject["tag"] = tag_;
235 jsonObject["options"] = nlohmann::json(options_);
236 jsonObject["permitFreeFormInput"] = permitFreeFormInput_;
237 jsonObject["permitMimeTypes"] = nlohmann::json(permitMimeTypes_);
238 jsonObject["editType"] = static_cast<int32_t>(editType_);
239 std::string additionalDataStr;
240 if (additionalData_) {
241 AAFwk::WantParamWrapper wWrapper(*additionalData_);
242 additionalDataStr = wWrapper.ToString();
243 }
244 jsonObject["additionalData"] = additionalDataStr;
245
246 return true;
247 }
248
FromJson(const nlohmann::json & jsonObject)249 NotificationUserInput *NotificationUserInput::FromJson(const nlohmann::json &jsonObject)
250 {
251 if (jsonObject.is_null() || !jsonObject.is_object()) {
252 ANS_LOGE("Invalid JSON object");
253 return nullptr;
254 }
255
256 auto pUserInput = new (std::nothrow) NotificationUserInput();
257 if (pUserInput == nullptr) {
258 ANS_LOGE("Failed to create userInput instance");
259 return nullptr;
260 }
261
262 const auto &jsonEnd = jsonObject.cend();
263 if (jsonObject.find("inputKey") != jsonEnd) {
264 pUserInput->inputKey_ = jsonObject.at("inputKey").get<std::string>();
265 }
266
267 if (jsonObject.find("tag") != jsonEnd) {
268 pUserInput->tag_ = jsonObject.at("tag").get<std::string>();
269 }
270
271 if (jsonObject.find("options") != jsonEnd) {
272 pUserInput->options_ = jsonObject.at("options").get<std::vector<std::string>>();
273 }
274
275 if (jsonObject.find("permitFreeFormInput") != jsonEnd) {
276 pUserInput->permitFreeFormInput_ = jsonObject.at("permitFreeFormInput").get<bool>();
277 }
278
279 if (jsonObject.find("permitMimeTypes") != jsonEnd) {
280 pUserInput->permitMimeTypes_ = jsonObject.at("permitMimeTypes").get<std::set<std::string>>();
281 }
282
283 if (jsonObject.find("additionalData") != jsonEnd) {
284 auto additionalDataString = jsonObject.at("additionalData").get<std::string>();
285 if (!additionalDataString.empty()) {
286 AAFwk::WantParams params = AAFwk::WantParamWrapper::ParseWantParams(additionalDataString);
287 pUserInput->additionalData_ = std::make_shared<AAFwk::WantParams>(params);
288 }
289 }
290
291 if (jsonObject.find("editType") != jsonEnd) {
292 auto editTypeValue = jsonObject.at("editType").get<int32_t>();
293 pUserInput->editType_ = static_cast<NotificationConstant::InputEditType>(editTypeValue);
294 }
295
296 return pUserInput;
297 }
298
Marshalling(Parcel & parcel) const299 bool NotificationUserInput::Marshalling(Parcel &parcel) const
300 {
301 if (!parcel.WriteString(inputKey_)) {
302 ANS_LOGE("Failed to write inputKey");
303 return false;
304 }
305
306 if (!parcel.WriteString(tag_)) {
307 ANS_LOGE("Failed to write tag");
308 return false;
309 }
310
311 if (!parcel.WriteBool(permitFreeFormInput_)) {
312 ANS_LOGE("Failed to write flag permitFreeFormInput");
313 return false;
314 }
315
316 if (!parcel.WriteInt32(static_cast<int32_t>(editType_))) {
317 ANS_LOGE("Failed to write editType");
318 return false;
319 }
320
321 auto valid = additionalData_ ? true : false;
322 if (!parcel.WriteBool(valid)) {
323 ANS_LOGE("Failed to write the flag which indicate whether additionalData is null");
324 return false;
325 }
326
327 if (valid) {
328 if (!parcel.WriteParcelable(additionalData_.get())) {
329 ANS_LOGE("Failed to write additionalData");
330 return false;
331 }
332 }
333
334 if (!parcel.WriteStringVector(options_)) {
335 ANS_LOGE("Failed to write options");
336 return false;
337 }
338
339 if (!parcel.WriteUint64(static_cast<uint64_t>(permitMimeTypes_.size()))) {
340 ANS_LOGE("Failed to write the size of permitMimeTypes");
341 return false;
342 }
343
344 for (auto it = permitMimeTypes_.begin(); it != permitMimeTypes_.end(); ++it) {
345 if (!parcel.WriteString(*it)) {
346 ANS_LOGE("Failed to write permitMimeTypes");
347 return false;
348 }
349 }
350
351 return true;
352 }
353
Unmarshalling(Parcel & parcel)354 NotificationUserInput *NotificationUserInput::Unmarshalling(Parcel &parcel)
355 {
356 auto pUserInput = new (std::nothrow) NotificationUserInput();
357 if ((pUserInput != nullptr) && !pUserInput->ReadFromParcel(parcel)) {
358 delete pUserInput;
359 pUserInput = nullptr;
360 }
361
362 return pUserInput;
363 }
364
ReadFromParcel(Parcel & parcel)365 bool NotificationUserInput::ReadFromParcel(Parcel &parcel)
366 {
367 if (!parcel.ReadString(inputKey_)) {
368 ANS_LOGE("Failed to read inputKey");
369 return false;
370 }
371
372 if (!parcel.ReadString(tag_)) {
373 ANS_LOGE("Failed to read tag");
374 return false;
375 }
376
377 permitFreeFormInput_ = parcel.ReadBool();
378
379 editType_ = static_cast<NotificationConstant::InputEditType>(parcel.ReadInt32());
380
381 auto valid = parcel.ReadBool();
382 if (valid) {
383 additionalData_ = std::shared_ptr<AAFwk::WantParams>(parcel.ReadParcelable<AAFwk::WantParams>());
384 if (!additionalData_) {
385 ANS_LOGE("Failed to read additionalData");
386 return false;
387 }
388 }
389
390 if (!parcel.ReadStringVector(&options_)) {
391 ANS_LOGE("Failed to read options");
392 return false;
393 }
394
395 auto ssize = parcel.ReadUint64();
396 for (uint64_t it = 0; it < ssize; ++it) {
397 std::string member {};
398 if (!parcel.ReadString(member)) {
399 ANS_LOGE("Failed to read permitMimeTypes");
400 return false;
401 }
402
403 permitMimeTypes_.emplace(member);
404 }
405
406 return true;
407 }
408 } // namespace Notification
409 } // namespace OHOS