• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_action_button.h"
17 
18 #include "ans_image_util.h"
19 #include "ans_log_wrapper.h"
20 #include "want_agent_helper.h"
21 #include "want_params_wrapper.h"
22 
23 namespace OHOS {
24 namespace Notification {
Create(const std::shared_ptr<Media::PixelMap> & icon,const std::string & title,const std::shared_ptr<AbilityRuntime::WantAgent::WantAgent> & wantAgent,const std::shared_ptr<AAFwk::WantParams> & extras,NotificationConstant::SemanticActionButton semanticActionButton,bool autoCreatedReplies,const std::vector<std::shared_ptr<NotificationUserInput>> & mimeTypeOnlyInputs,const std::shared_ptr<NotificationUserInput> & userInput,bool isContextual)25 std::shared_ptr<NotificationActionButton> NotificationActionButton::Create(const std::shared_ptr<Media::PixelMap> &icon,
26     const std::string &title, const std::shared_ptr<AbilityRuntime::WantAgent::WantAgent> &wantAgent,
27     const std::shared_ptr<AAFwk::WantParams> &extras, NotificationConstant::SemanticActionButton semanticActionButton,
28     bool autoCreatedReplies, const std::vector<std::shared_ptr<NotificationUserInput>> &mimeTypeOnlyInputs,
29     const std::shared_ptr<NotificationUserInput> &userInput, bool isContextual)
30 {
31     if (isContextual && (!icon || !wantAgent)) {
32         ANS_LOGE("icon or wantAgent can not be null when isContextual is true");
33         return {};
34     }
35 
36     auto realExtras = extras;
37     if (!realExtras) {
38         realExtras = std::make_shared<AAFwk::WantParams>();
39         if (!realExtras) {
40             ANS_LOGE("create WantParams object failed");
41             return {};
42         }
43     }
44 
45     std::shared_ptr<NotificationUserInput> textInput = userInput;
46     std::vector<std::shared_ptr<NotificationUserInput>> onlyInputs = mimeTypeOnlyInputs;
47     if (userInput && (userInput->IsMimeTypeOnly())) {
48         onlyInputs.push_back(userInput);
49     }
50 
51     auto pActionButton = new (std::nothrow) NotificationActionButton(icon,
52         title,
53         wantAgent,
54         realExtras,
55         semanticActionButton,
56         autoCreatedReplies,
57         onlyInputs,
58         textInput,
59         isContextual);
60     if (pActionButton == nullptr) {
61         ANS_LOGE("create NotificationActionButton object failed");
62         return {};
63     }
64 
65     return std::shared_ptr<NotificationActionButton>(pActionButton);
66 }
67 
Create(const std::shared_ptr<NotificationActionButton> & actionButton)68 std::shared_ptr<NotificationActionButton> NotificationActionButton::Create(
69     const std::shared_ptr<NotificationActionButton> &actionButton)
70 {
71     if (!actionButton) {
72         ANS_LOGW("invalid input NotificationActionButton object");
73         return {};
74     }
75 
76     return NotificationActionButton::Create(actionButton->GetIcon(),
77         actionButton->GetTitle(),
78         actionButton->GetWantAgent(),
79         actionButton->GetAdditionalData(),
80         actionButton->GetSemanticActionButton(),
81         actionButton->IsAutoCreatedReplies(),
82         actionButton->GetMimeTypeOnlyUserInputs(),
83         actionButton->GetUserInput(),
84         actionButton->IsContextDependent());
85 }
86 
NotificationActionButton(const std::shared_ptr<Media::PixelMap> & icon,const std::string & title,const std::shared_ptr<AbilityRuntime::WantAgent::WantAgent> & wantAgent,const std::shared_ptr<AAFwk::WantParams> & extras,NotificationConstant::SemanticActionButton semanticActionButton,bool autoCreatedReplies,const std::vector<std::shared_ptr<NotificationUserInput>> & mimeTypeOnlyInputs,const std::shared_ptr<NotificationUserInput> & userInput,bool isContextual)87 NotificationActionButton::NotificationActionButton(const std::shared_ptr<Media::PixelMap> &icon,
88     const std::string &title, const std::shared_ptr<AbilityRuntime::WantAgent::WantAgent> &wantAgent,
89     const std::shared_ptr<AAFwk::WantParams> &extras, NotificationConstant::SemanticActionButton semanticActionButton,
90     bool autoCreatedReplies, const std::vector<std::shared_ptr<NotificationUserInput>> &mimeTypeOnlyInputs,
91     const std::shared_ptr<NotificationUserInput> &userInput, bool isContextual)
92     : icon_(icon),
93       title_(title),
94       wantAgent_(wantAgent),
95       extras_(extras),
96       semanticActionButton_(semanticActionButton),
97       autoCreatedReplies_(autoCreatedReplies),
98       mimeTypeOnlyUserInputs_(mimeTypeOnlyInputs),
99       userInput_(userInput),
100       isContextual_(isContextual)
101 {}
102 
GetIcon() const103 const std::shared_ptr<Media::PixelMap> NotificationActionButton::GetIcon() const
104 {
105     return icon_;
106 }
107 
GetTitle() const108 std::string NotificationActionButton::GetTitle() const
109 {
110     return title_;
111 }
112 
GetWantAgent() const113 const std::shared_ptr<AbilityRuntime::WantAgent::WantAgent> NotificationActionButton::GetWantAgent() const
114 {
115     return wantAgent_;
116 }
117 
AddAdditionalData(AAFwk::WantParams & extras)118 void NotificationActionButton::AddAdditionalData(AAFwk::WantParams &extras)
119 {
120     if (extras_) {
121         *extras_ = extras;
122     }
123 }
124 
GetAdditionalData() const125 const std::shared_ptr<AAFwk::WantParams> NotificationActionButton::GetAdditionalData() const
126 {
127     return extras_;
128 }
129 
SetSemanticActionButton(NotificationConstant::SemanticActionButton semanticActionButton)130 void NotificationActionButton::SetSemanticActionButton(NotificationConstant::SemanticActionButton semanticActionButton)
131 {
132     semanticActionButton_ = semanticActionButton;
133 }
134 
GetSemanticActionButton() const135 NotificationConstant::SemanticActionButton NotificationActionButton::GetSemanticActionButton() const
136 {
137     return semanticActionButton_;
138 }
139 
AddMimeTypeOnlyUserInput(const std::shared_ptr<NotificationUserInput> & userInput)140 void NotificationActionButton::AddMimeTypeOnlyUserInput(const std::shared_ptr<NotificationUserInput> &userInput)
141 {
142     if (!userInput) {
143         ANS_LOGE("The userInput is invalid.");
144         return;
145     }
146 
147     if (!userInput->IsMimeTypeOnly()) {
148         ANS_LOGE("The userInput is not a particular MIME types.");
149         return;
150     }
151 
152     mimeTypeOnlyUserInputs_.emplace_back(userInput);
153 }
154 
GetMimeTypeOnlyUserInputs() const155 std::vector<std::shared_ptr<NotificationUserInput>> NotificationActionButton::GetMimeTypeOnlyUserInputs() const
156 {
157     return mimeTypeOnlyUserInputs_;
158 }
159 
AddNotificationUserInput(const std::shared_ptr<NotificationUserInput> & userInput)160 void NotificationActionButton::AddNotificationUserInput(const std::shared_ptr<NotificationUserInput> &userInput)
161 {
162     userInput_ = userInput;
163 }
164 
GetUserInput() const165 const std::shared_ptr<NotificationUserInput> NotificationActionButton::GetUserInput() const
166 {
167     return userInput_;
168 }
169 
SetAutoCreatedReplies(bool autoCreatedReplies)170 void NotificationActionButton::SetAutoCreatedReplies(bool autoCreatedReplies)
171 {
172     autoCreatedReplies_ = autoCreatedReplies;
173 }
174 
IsAutoCreatedReplies() const175 bool NotificationActionButton::IsAutoCreatedReplies() const
176 {
177     return autoCreatedReplies_;
178 }
179 
SetContextDependent(bool isContextual)180 void NotificationActionButton::SetContextDependent(bool isContextual)
181 {
182     isContextual_ = isContextual;
183 }
184 
IsContextDependent() const185 bool NotificationActionButton::IsContextDependent() const
186 {
187     return isContextual_;
188 }
189 
Dump()190 std::string NotificationActionButton::Dump()
191 {
192     std::string mimeTypeOnlyUserInputs = "";
193     for (auto &item : mimeTypeOnlyUserInputs_) {
194         if (!item) {
195             mimeTypeOnlyUserInputs += "nullptr, ";
196             continue;
197         }
198         mimeTypeOnlyUserInputs += item->Dump();
199         mimeTypeOnlyUserInputs += ", ";
200     }
201 
202     std::string userInput = "";
203     if (userInput_ == nullptr) {
204         userInput += "nullptr, ";
205     } else {
206         userInput += userInput_->Dump();
207         userInput += ", ";
208     }
209 
210     return "NotificationActionButton{ "
211             "title = " + title_ +
212             ", semanticActionButton = " + std::to_string(static_cast<int32_t>(semanticActionButton_)) +
213             ", autoCreatedReplies = " + (autoCreatedReplies_ ? "true" : "false") +
214             ", isContextual = " + (isContextual_ ? "true" : "false") +
215             ", mimeTypeOnlyUserInputs = [" + mimeTypeOnlyUserInputs + "]" +
216             ", userInputs = [" + userInput + "]" +
217             " }";
218 }
219 
ToJson(nlohmann::json & jsonObject) const220 bool NotificationActionButton::ToJson(nlohmann::json &jsonObject) const
221 {
222     jsonObject["icon"]      = AnsImageUtil::PackImage(icon_);
223     jsonObject["title"]     = title_;
224     jsonObject["wantAgent"] = wantAgent_ ? AbilityRuntime::WantAgent::WantAgentHelper::ToString(wantAgent_) : "";
225 
226     std::string extrasStr;
227     if (extras_) {
228         AAFwk::WantParamWrapper wWrapper(*extras_);
229         extrasStr = wWrapper.ToString();
230     }
231     jsonObject["extras"] = extrasStr;
232 
233     return true;
234 }
235 
FromJson(const nlohmann::json & jsonObject)236 NotificationActionButton *NotificationActionButton::FromJson(const nlohmann::json &jsonObject)
237 {
238     if (jsonObject.is_null() or !jsonObject.is_object()) {
239         ANS_LOGE("Invalid JSON object");
240         return nullptr;
241     }
242 
243     auto pButton = new (std::nothrow) NotificationActionButton();
244     if (pButton == nullptr) {
245         ANS_LOGE("Failed to create actionButton instance");
246         return nullptr;
247     }
248 
249     const auto &jsonEnd = jsonObject.cend();
250     if (jsonObject.find("icon") != jsonEnd && jsonObject.at("icon").is_string()) {
251         auto iconStr   = jsonObject.at("icon").get<std::string>();
252         pButton->icon_ = AnsImageUtil::UnPackImage(iconStr);
253     }
254 
255     if (jsonObject.find("title") != jsonEnd && jsonObject.at("title").is_string()) {
256         pButton->title_ = jsonObject.at("title").get<std::string>();
257     }
258 
259     if (jsonObject.find("wantAgent") != jsonEnd && jsonObject.at("wantAgent").is_string()) {
260         auto wantAgentValue = jsonObject.at("wantAgent").get<std::string>();
261         pButton->wantAgent_ = AbilityRuntime::WantAgent::WantAgentHelper::FromString(wantAgentValue);
262     }
263 
264     if (jsonObject.find("extras") != jsonEnd && jsonObject.at("extras").is_string()) {
265         auto extrasString = jsonObject.at("extras").get<std::string>();
266         if (!extrasString.empty()) {
267             AAFwk::WantParams params = AAFwk::WantParamWrapper::ParseWantParams(extrasString);
268             pButton->extras_ = std::make_shared<AAFwk::WantParams>(params);
269         }
270     }
271 
272     return pButton;
273 }
274 
Marshalling(Parcel & parcel) const275 bool NotificationActionButton::Marshalling(Parcel &parcel) const
276 {
277     if (!parcel.WriteString(title_)) {
278         ANS_LOGE("Failed to write title");
279         return false;
280     }
281 
282     if (!parcel.WriteBool(autoCreatedReplies_)) {
283         ANS_LOGE("Failed to write flag autoCreatedReplies");
284         return false;
285     }
286 
287     if (!parcel.WriteBool(isContextual_)) {
288         ANS_LOGE("Failed to write flag isContextual");
289         return false;
290     }
291 
292     if (!parcel.WriteInt32(static_cast<int32_t>(semanticActionButton_))) {
293         ANS_LOGE("Failed to write semanticActionButton");
294         return false;
295     }
296 
297     bool valid {false};
298 
299     valid = icon_ ? true : false;
300     if (!parcel.WriteBool(valid)) {
301         ANS_LOGE("Failed to write the flag which indicate whether icon is null");
302         return false;
303     }
304 
305     if (valid) {
306         if (!parcel.WriteParcelable(icon_.get())) {
307             ANS_LOGE("Failed to write icon");
308             return false;
309         }
310     }
311 
312     valid = wantAgent_ ? true : false;
313     if (!parcel.WriteBool(valid)) {
314         ANS_LOGE("Failed to write the flag which indicate whether wantAgent is null");
315         return false;
316     }
317 
318     if (valid) {
319         if (!parcel.WriteParcelable(wantAgent_.get())) {
320             ANS_LOGE("Failed to write wantAgent");
321             return false;
322         }
323     }
324 
325     valid = extras_ ? true : false;
326     if (!parcel.WriteBool(valid)) {
327         ANS_LOGE("Failed to write the flag which indicate whether extras is null");
328         return false;
329     }
330 
331     if (valid) {
332         if (!parcel.WriteParcelable(extras_.get())) {
333             ANS_LOGE("Failed to write extras");
334             return false;
335         }
336     }
337 
338     valid = userInput_ ? true : false;
339     if (!parcel.WriteBool(valid)) {
340         ANS_LOGE("Failed to write the flag which indicate whether userInput is null");
341         return false;
342     }
343 
344     if (valid) {
345         if (!parcel.WriteParcelable(userInput_.get())) {
346             ANS_LOGE("Failed to write userInput");
347             return false;
348         }
349     }
350 
351     return true;
352 }
353 
Unmarshalling(Parcel & parcel)354 NotificationActionButton *NotificationActionButton::Unmarshalling(Parcel &parcel)
355 {
356     auto pButton = new (std::nothrow) NotificationActionButton();
357     if ((pButton != nullptr) && !pButton->ReadFromParcel(parcel)) {
358         delete pButton;
359         pButton = nullptr;
360     }
361 
362     return pButton;
363 }
364 
ReadFromParcel(Parcel & parcel)365 bool NotificationActionButton::ReadFromParcel(Parcel &parcel)
366 {
367     if (!parcel.ReadString(title_)) {
368         ANS_LOGE("Failed to read title");
369         return false;
370     }
371 
372     autoCreatedReplies_ = parcel.ReadBool();
373 
374     isContextual_ = parcel.ReadBool();
375 
376     semanticActionButton_ = static_cast<NotificationConstant::SemanticActionButton>(parcel.ReadInt32());
377 
378     bool valid {false};
379 
380     valid = parcel.ReadBool();
381     if (valid) {
382         icon_ = std::shared_ptr<Media::PixelMap>(parcel.ReadParcelable<Media::PixelMap>());
383         if (!icon_) {
384             ANS_LOGE("Failed to read icon");
385             return false;
386         }
387     }
388 
389     valid = parcel.ReadBool();
390     if (valid) {
391         wantAgent_ = std::shared_ptr<AbilityRuntime::WantAgent::WantAgent>(
392             parcel.ReadParcelable<AbilityRuntime::WantAgent::WantAgent>());
393         if (!wantAgent_) {
394             ANS_LOGE("Failed to read wantAgent");
395             return false;
396         }
397     }
398 
399     valid = parcel.ReadBool();
400     if (valid) {
401         extras_ = std::shared_ptr<AAFwk::WantParams>(parcel.ReadParcelable<AAFwk::WantParams>());
402         if (!extras_) {
403             ANS_LOGE("Failed to read extras");
404             return false;
405         }
406     }
407 
408     valid = parcel.ReadBool();
409     if (valid) {
410         userInput_ = std::shared_ptr<NotificationUserInput>(parcel.ReadParcelable<NotificationUserInput>());
411         if (!userInput_) {
412             ANS_LOGE("Failed to read userInput");
413             return false;
414         }
415     }
416 
417     return true;
418 }
419 }  // namespace Notification
420 }  // namespace OHOS
421