1 /*
2  * Copyright (c) 2024 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_utils.h"
17 #include "notification_manager_log.h"
18 
19 namespace OHOS {
20 namespace CJSystemapi {
21 namespace Notification {
22     using namespace OHOS::FFI;
23     using namespace OHOS::Notification;
24 
MallocCString(const std::string &origin)25     char *MallocCString(const std::string &origin)
26     {
27         if (origin.empty()) {
28             return nullptr;
29         }
30         auto len = origin.length() + 1;
31         char *res = static_cast<char *>(malloc(sizeof(char) * len));
32         if (res == nullptr) {
33             return nullptr;
34         }
35         return std::char_traits<char>::copy(res, origin.c_str(), len);
36     }
37 
GetNotificationSupportDisplayDevices( CDistributedOptions* distributedOption, NotificationRequest request)38     bool GetNotificationSupportDisplayDevices(
39         CDistributedOptions* distributedOption,
40         NotificationRequest request)
41     {
42         int64_t length = distributedOption->supportDisplayDevices.size;
43         if (length == 0) {
44             LOGE("The array is empty.");
45             return false;
46         }
47         std::vector<std::string> devices;
48         for (int64_t i = 0; i < length; i++) {
49             char str[STR_MAX_SIZE] = {0};
50             auto displayDevice = distributedOption->supportDisplayDevices.head[i];
51             if (strcpy_s(str, STR_MAX_SIZE, displayDevice) != EOK) {
52                 return false;
53             }
54             devices.emplace_back(str);
55             LOGI("supportDisplayDevices = %{public}s", str);
56         }
57         request.SetDevicesSupportDisplay(devices);
58         return true;
59     }
60 
GetNotificationSupportOperateDevices( CDistributedOptions* distributedOption, NotificationRequest request)61     bool GetNotificationSupportOperateDevices(
62         CDistributedOptions* distributedOption,
63         NotificationRequest request)
64     {
65         int64_t length = distributedOption->supportOperateDevices.size;
66         if (length == 0) {
67             LOGE("The array is empty.");
68             return false;
69         }
70         std::vector<std::string> devices;
71         for (int64_t i = 0; i < length; i++) {
72             char str[STR_MAX_SIZE] = {0};
73             auto operateDevice = distributedOption->supportOperateDevices.head[i];
74             if (strcpy_s(str, STR_MAX_SIZE, operateDevice) != EOK) {
75                 return false;
76             }
77             devices.emplace_back(str);
78             LOGI("supportOperateDevices = %{public}s", str);
79         }
80         request.SetDevicesSupportOperate(devices);
81         return true;
82     }
83 
GetNotificationRequestDistributedOptions( CDistributedOptions* distributedOption, NotificationRequest request)84     bool GetNotificationRequestDistributedOptions(
85         CDistributedOptions* distributedOption,
86         NotificationRequest request)
87     {
88         if (distributedOption != nullptr) {
89             // isDistributed?: boolean
90             request.SetDistributed(distributedOption->isDistributed);
91 
92             // supportDisplayDevices?: Array<string>
93             if (!GetNotificationSupportDisplayDevices(distributedOption, request)) {
94                 return false;
95             }
96 
97             // supportOperateDevices?: Array<string>
98             if (!GetNotificationSupportOperateDevices(distributedOption, request)) {
99                 return false;
100             }
101         }
102         return true;
103     }
104 
GetNotificationRequestByNumber(CNotificationRequest cjRequest, NotificationRequest &request)105     bool GetNotificationRequestByNumber(CNotificationRequest cjRequest, NotificationRequest &request)
106     {
107         // id?: int32_t
108         int32_t id = cjRequest.id;
109         request.SetNotificationId(id);
110 
111         // deliveryTime?: int64_t
112         int64_t deliveryTime = cjRequest.deliveryTime;
113         request.SetDeliveryTime(deliveryTime);
114 
115         // autoDeletedTime?: int64_t
116         int64_t autoDeletedTime = cjRequest.autoDeletedTime;
117         request.SetAutoDeletedTime(autoDeletedTime);
118 
119         // color?: uint32_t
120         request.SetColor(cjRequest.color);
121 
122         // badgeIconStyle?: int32_t
123         int32_t badgeIconStyle = cjRequest.badgeIconStyle;
124         request.SetBadgeIconStyle(static_cast<NotificationRequest::BadgeStyle>(badgeIconStyle));
125 
126         // badgeNumber?: uint32_t
127         uint32_t badgeNumber = cjRequest.badgeNumber;
128         if (badgeNumber < 0) {
129             LOGE("Wrong badge number.");
130             return false;
131         }
132         request.SetBadgeNumber(badgeNumber);
133 
134         return true;
135     }
136 
GetNotificationRequestByString(CNotificationRequest cjRequest, NotificationRequest &request)137     bool GetNotificationRequestByString(CNotificationRequest cjRequest, NotificationRequest &request)
138     {
139         // label?: string
140         char label[STR_MAX_SIZE] = {0};
141         if (strcpy_s(label, STR_MAX_SIZE, cjRequest.label) != EOK) {
142             return false;
143         }
144         request.SetLabel(std::string(label));
145 
146         // groupName?: string
147         char groupName[STR_MAX_SIZE] = {0};
148         if (strcpy_s(groupName, STR_MAX_SIZE, cjRequest.groupName) != EOK) {
149             return false;
150         }
151         request.SetGroupName(std::string(groupName));
152 
153         // groupName?: string
154         char appMessageId[STR_MAX_SIZE] = {0};
155         if (strcpy_s(appMessageId, STR_MAX_SIZE, cjRequest.appMessageId) != EOK) {
156             return false;
157         }
158         request.SetAppMessageId(std::string(appMessageId));
159 
160         return true;
161     }
162 
GetNotificationRequestByBool(CNotificationRequest cjRequest, NotificationRequest &request)163     bool GetNotificationRequestByBool(CNotificationRequest cjRequest, NotificationRequest &request)
164     {
165         // isOngoing?: boolean
166         bool isOngoing = cjRequest.isOngoing;
167         request.SetInProgress(isOngoing);
168 
169         // isUnremovable?: boolean
170         bool isUnremovable = cjRequest.isUnremovable;
171         request.SetUnremovable(isUnremovable);
172 
173         // tapDismissed?: boolean
174         bool tapDismissed = cjRequest.tapDismissed;
175         request.SetTapDismissed(tapDismissed);
176 
177         // colorEnabled?: boolean
178         bool colorEnabled = cjRequest.colorEnabled;
179         request.SetColorEnabled(colorEnabled);
180 
181         // isAlertOnce?: boolean
182         bool isAlertOnce = cjRequest.isAlertOnce;
183         request.SetAlertOneTime(isAlertOnce);
184 
185         // isStopwatch?: boole
186         bool isStopwatch = cjRequest.isStopwatch;
187         request.SetShowStopwatch(isStopwatch);
188 
189         // isCountDown?: boolean
190         bool isCountDown = cjRequest.isCountDown;
191         request.SetCountdownTimer(isCountDown);
192 
193         // showDeliveryTime?: boolean
194         bool showDeliveryTime = cjRequest.showDeliveryTime;
195         request.SetShowDeliveryTime(showDeliveryTime);
196 
197         return true;
198     }
199 
GetNotificationRequestByCustom(CNotificationRequest cjRequest, NotificationRequest &request)200     bool GetNotificationRequestByCustom(CNotificationRequest cjRequest, NotificationRequest &request)
201     {
202         // content: NotificationContent
203         if (!GetNotificationContent(cjRequest.notificationContent, request)) {
204             return false;
205         }
206         // slotType?: notification.SlotType
207         if (!GetNotificationSlotType(cjRequest.notificationSlotType, request)) {
208             return false;
209         }
210         // smallIcon?: image.PixelMap
211         if (!GetNotificationSmallIcon(cjRequest.smallIcon, request)) {
212             return false;
213         }
214         // largeIcon?: image.PixelMap
215         if (!GetNotificationLargeIcon(cjRequest.largeIcon, request)) {
216             return false;
217         }
218         // distributedOption?:DistributedOptions
219         if (!GetNotificationRequestDistributedOptions(cjRequest.distributedOption, request)) {
220             return false;
221         }
222 
223         return true;
224     }
225 
GetNotificationBasicContentDetailed(CNotificationBasicContent* contentResult, std::shared_ptr<NotificationBasicContent> basicContent)226     bool GetNotificationBasicContentDetailed(CNotificationBasicContent* contentResult,
227         std::shared_ptr<NotificationBasicContent> basicContent)
228     {
229         char str[STR_MAX_SIZE] = {0};
230         // title: String
231         if (strcpy_s(str, STR_MAX_SIZE, contentResult->title) != EOK) {
232             return false;
233         }
234         if (strlen(str) == 0) {
235             LOGE("Property title is empty");
236             return false;
237         }
238         basicContent->SetTitle(std::string(str));
239         // text: String
240         if (strcpy_s(str, STR_MAX_SIZE, contentResult->text) != EOK) {
241             return false;
242         }
243         if (strlen(str) == 0) {
244             LOGE("Property text is empty");
245             return false;
246         }
247         basicContent->SetText(std::string(str));
248         // additionalText: string
249         if (strcpy_s(str, STR_MAX_SIZE, contentResult->additionalText) != EOK) {
250             return false;
251         }
252         basicContent->SetAdditionalText(std::string(str));
253 
254         // lockScreenPicture?: pixelMap
255         if (contentResult->lockscreenPicture != -1) {
256             auto pixelMap = FFIData::GetData<Media::PixelMapImpl>(contentResult->lockscreenPicture);
257             if (pixelMap == nullptr) {
258                 LOGE("Invalid object pixelMap");
259                 return false;
260             }
261             basicContent->SetLockScreenPicture(pixelMap->GetRealPixelMap());
262         }
263         return true;
264     }
265 
GetNotificationBasicContent(CNotificationBasicContent* contentResult, NotificationRequest &request)266     bool GetNotificationBasicContent(CNotificationBasicContent* contentResult, NotificationRequest &request)
267     {
268         std::shared_ptr<NotificationNormalContent> normalContent = std::make_shared<NotificationNormalContent>();
269         if (normalContent == nullptr) {
270             LOGE("normalContent is null");
271             return false;
272         }
273 
274         if (!GetNotificationBasicContentDetailed(contentResult, normalContent)) {
275             return false;
276         }
277         request.SetContent(std::make_shared<NotificationContent>(normalContent));
278         return true;
279     }
280 
GetNotificationLongTextContentDetailed( CNotificationLongTextContent* contentResult, std::shared_ptr<NotificationLongTextContent> &longContent)281     bool GetNotificationLongTextContentDetailed(
282         CNotificationLongTextContent* contentResult,
283         std::shared_ptr<NotificationLongTextContent> &longContent)
284     {
285         char str[STR_MAX_SIZE] = {0};
286         char long_str[LONG_STR_MAX_SIZE + 1] = {0};
287 
288         std::shared_ptr<CNotificationBasicContent> tempContent = std::make_shared<CNotificationBasicContent>();
289         tempContent->title = contentResult->title;
290         tempContent->text = contentResult->text;
291         tempContent->additionalText = contentResult->additionalText;
292         tempContent->lockscreenPicture = contentResult->lockscreenPicture;
293         if (!GetNotificationBasicContentDetailed(tempContent.get(), longContent)) {
294             return false;
295         }
296 
297         // longText: String
298         if (strcpy_s(long_str, LONG_STR_MAX_SIZE + 1, contentResult->longText) != EOK) {
299             return false;
300         }
301         if (strlen(long_str) == 0) {
302             LOGE("Property longText is empty");
303             return false;
304         }
305         longContent->SetLongText(std::string(long_str));
306 
307         // briefText: String
308         if (strcpy_s(str, STR_MAX_SIZE, contentResult->briefText) != EOK) {
309             return false;
310         }
311         if (strlen(str) == 0) {
312             LOGE("Property briefText is empty");
313             return false;
314         }
315         longContent->SetBriefText(std::string(str));
316 
317         // expandedTitle: String
318         if (strcpy_s(str, STR_MAX_SIZE, contentResult->expandedTitle) != EOK) {
319             return false;
320         }
321         if (strlen(str) == 0) {
322             LOGE("Property expandedTitle is empty");
323             return false;
324         }
325         longContent->SetExpandedTitle(std::string(str));
326 
327         return true;
328     }
329 
GetNotificationLongTextContent( CNotificationLongTextContent* contentResult, NotificationRequest &request)330     bool GetNotificationLongTextContent(
331         CNotificationLongTextContent* contentResult,
332         NotificationRequest &request)
333     {
334         std::shared_ptr<OHOS::Notification::NotificationLongTextContent> longContent =
335         std::make_shared<OHOS::Notification::NotificationLongTextContent>();
336         if (longContent == nullptr) {
337             LOGE("longContent is null");
338             return false;
339         }
340         if (!GetNotificationLongTextContentDetailed(contentResult, longContent)) {
341             return false;
342         }
343 
344         request.SetContent(std::make_shared<NotificationContent>(longContent));
345         return true;
346     }
347 
GetNotificationPictureContentDetailed( CNotificationPictureContent* contentResult, std::shared_ptr<NotificationPictureContent> &pictureContent)348     bool GetNotificationPictureContentDetailed(
349         CNotificationPictureContent* contentResult,
350         std::shared_ptr<NotificationPictureContent> &pictureContent)
351     {
352         char str[STR_MAX_SIZE] = {0};
353 
354         std::shared_ptr<CNotificationBasicContent> tempContent = std::make_shared<CNotificationBasicContent>();
355         tempContent->title = contentResult->title;
356         tempContent->text = contentResult->text;
357         tempContent->additionalText = contentResult->additionalText;
358         tempContent->lockscreenPicture = contentResult->lockscreenPicture;
359         if (!GetNotificationBasicContentDetailed(tempContent.get(), pictureContent)) {
360             return false;
361         }
362 
363         // briefText: String
364         if (strcpy_s(str, STR_MAX_SIZE, contentResult->briefText) != EOK) {
365             return false;
366         }
367         if (std::strlen(str) == 0) {
368             LOGE("Property briefText is empty");
369             return false;
370         }
371         pictureContent->SetBriefText(std::string(str));
372 
373         // expandedTitle: String
374         if (strcpy_s(str, STR_MAX_SIZE, contentResult->expandedTitle) != EOK) {
375             return false;
376         }
377         if (std::strlen(str) == 0) {
378             LOGE("Property expandedTitle is empty");
379             return false;
380         }
381         pictureContent->SetExpandedTitle(std::string(str));
382 
383         // picture: image.PixelMap
384         auto pixelMap = FFIData::GetData<Media::PixelMapImpl>(contentResult->picture);
385         if (pixelMap == nullptr) {
386             LOGE("Invalid object pixelMap");
387             return false;
388         }
389         pictureContent->SetBigPicture(pixelMap->GetRealPixelMap());
390 
391         return true;
392     }
393 
GetNotificationPictureContent( CNotificationPictureContent* contentResult, NotificationRequest &request)394     bool GetNotificationPictureContent(
395         CNotificationPictureContent* contentResult,
396         NotificationRequest &request)
397     {
398         std::shared_ptr<OHOS::Notification::NotificationPictureContent> pictureContent =
399         std::make_shared<OHOS::Notification::NotificationPictureContent>();
400         if (pictureContent == nullptr) {
401             LOGE("pictureContent is null");
402             return false;
403         }
404 
405         if (!GetNotificationPictureContentDetailed(contentResult, pictureContent)) {
406             return false;
407         }
408 
409         request.SetContent(std::make_shared<NotificationContent>(pictureContent));
410         return true;
411     }
412 
GetNotificationMultiLineContentLines( CNotificationMultiLineContent* result, std::shared_ptr<OHOS::Notification::NotificationMultiLineContent> &multiLineContent)413     bool GetNotificationMultiLineContentLines(
414         CNotificationMultiLineContent* result,
415         std::shared_ptr<OHOS::Notification::NotificationMultiLineContent> &multiLineContent)
416     {
417         char str[STR_MAX_SIZE] = {0};
418         int64_t length = result->lines.size;
419         if (length == 0) {
420             LOGE("The array is empty.");
421             return false;
422         }
423         for (int64_t i = 0; i < length; i++) {
424             if (strcpy_s(str, STR_MAX_SIZE, result->lines.head[i]) != EOK) {
425                 return false;
426             }
427             multiLineContent->AddSingleLine(std::string(str));
428         }
429         return true;
430     }
431 
GetNotificationMultiLineContent( CNotificationMultiLineContent* contentResult, NotificationRequest &request)432     bool GetNotificationMultiLineContent(
433         CNotificationMultiLineContent* contentResult,
434         NotificationRequest &request)
435     {
436         char str[STR_MAX_SIZE] = {0};
437 
438         std::shared_ptr<OHOS::Notification::NotificationMultiLineContent> multiLineContent =
439         std::make_shared<OHOS::Notification::NotificationMultiLineContent>();
440         if (multiLineContent == nullptr) {
441             LOGE("multiLineContent is null");
442             return false;
443         }
444 
445         std::shared_ptr<CNotificationBasicContent> tempContent = std::make_shared<CNotificationBasicContent>();
446         tempContent->title = contentResult->title;
447         tempContent->text = contentResult->text;
448         tempContent->additionalText = contentResult->additionalText;
449         tempContent->lockscreenPicture = contentResult->lockscreenPicture;
450         if (!GetNotificationBasicContentDetailed(tempContent.get(), multiLineContent)) {
451             return false;
452         }
453 
454         // briefText: String
455         if (strcpy_s(str, STR_MAX_SIZE, contentResult->briefText) != EOK) {
456             return false;
457         }
458         if (std::strlen(str) == 0) {
459             LOGE("Property briefText is empty");
460             return false;
461         }
462         multiLineContent->SetBriefText(std::string(str));
463 
464         // longTitle: String
465         if (strcpy_s(str, STR_MAX_SIZE, contentResult->longTitle) != EOK) {
466             return false;
467         }
468         if (std::strlen(str) == 0) {
469             LOGE("Property longTitle is empty");
470             return false;
471         }
472         multiLineContent->SetExpandedTitle(std::string(str));
473 
474         // lines: Array<String>
475         if (!GetNotificationMultiLineContentLines(contentResult, multiLineContent)) {
476             return false;
477         }
478 
479         request.SetContent(std::make_shared<NotificationContent>(multiLineContent));
480         return true;
481     }
482 
GetNotificationLocalLiveViewCapsule(CNotificationSystemLiveViewContent* contentResult, std::shared_ptr<NotificationLocalLiveViewContent> &content)483     bool GetNotificationLocalLiveViewCapsule(CNotificationSystemLiveViewContent* contentResult,
484         std::shared_ptr<NotificationLocalLiveViewContent> &content)
485     {
486         char str[STR_MAX_SIZE] = {0};
487         NotificationCapsule capsule;
488         if (strcpy_s(str, STR_MAX_SIZE, contentResult->capsule.title) != EOK) {
489             LOGE("copy capsule.title failed");
490             return false;
491         }
492         capsule.SetTitle(std::string(str));
493 
494         if (strcpy_s(str, STR_MAX_SIZE, contentResult->capsule.backgroundColor) != EOK) {
495             LOGE("copy capsule.backgroundColor failed");
496             return false;
497         }
498         capsule.SetBackgroundColor(std::string(str));
499 
500         if (contentResult->capsule.icon != -1) {
501             auto pixelMap = FFIData::GetData<Media::PixelMapImpl>(contentResult->capsule.icon);
502             if (pixelMap == nullptr) {
503                 LOGE("Invalid object pixelMap");
504                 return false;
505             }
506             capsule.SetIcon(pixelMap->GetRealPixelMap());
507         }
508 
509         content->SetCapsule(capsule);
510         content->addFlag(NotificationLocalLiveViewContent::LiveViewContentInner::CAPSULE);
511         return true;
512     }
513 
GetNotificationLocalLiveViewButton(CNotificationSystemLiveViewContent* contentResult, std::shared_ptr<NotificationLocalLiveViewContent> &content)514     bool GetNotificationLocalLiveViewButton(CNotificationSystemLiveViewContent* contentResult,
515         std::shared_ptr<NotificationLocalLiveViewContent> &content)
516     {
517         char str[STR_MAX_SIZE] = {0};
518         NotificationLocalLiveViewButton button;
519         int64_t length = contentResult->button.names.size;
520         for (int64_t i = 0; i < length; i++) {
521             if (strcpy_s(str, STR_MAX_SIZE, contentResult->button.names.head[i]) != EOK) {
522                 LOGE("copy button.names failed");
523                 return false;
524             }
525             button.addSingleButtonName(std::string(str));
526         }
527 
528         length = contentResult->button.icons.size;
529         for (int64_t i = 0; i < length; i++) {
530             int64_t id = contentResult->button.icons.head[i];
531             auto pixelMap = FFIData::GetData<Media::PixelMapImpl>(id);
532             if (pixelMap == nullptr) {
533                 LOGE("Invalid object pixelMap");
534                 return false;
535             }
536             auto pix = pixelMap->GetRealPixelMap();
537             if (pix != nullptr && static_cast<uint32_t>(pix->GetByteCount()) <= MAX_ICON_SIZE) {
538                 button.addSingleButtonIcon(pix);
539             } else {
540                 LOGE("Invalid pixelMap object or pixelMap is over size.");
541                 return false;
542             }
543         }
544         content->SetButton(button);
545         content->addFlag(NotificationLocalLiveViewContent::LiveViewContentInner::BUTTON);
546         return true;
547     }
548 
GetNotificationLocalLiveViewProgress(CNotificationSystemLiveViewContent* contentResult, std::shared_ptr<NotificationLocalLiveViewContent> &content)549     bool GetNotificationLocalLiveViewProgress(CNotificationSystemLiveViewContent* contentResult,
550         std::shared_ptr<NotificationLocalLiveViewContent> &content)
551     {
552         NotificationProgress progress;
553         if (contentResult->progress.maxValue < 0 || contentResult->progress.currentValue < 0) {
554             LOGE("Wrong argument value. Number expected.");
555             return false;
556         }
557         progress.SetMaxValue(contentResult->progress.maxValue);
558         progress.SetCurrentValue(contentResult->progress.currentValue);
559         progress.SetIsPercentage(contentResult->progress.isPercentage);
560 
561         content->SetProgress(progress);
562         content->addFlag(NotificationLocalLiveViewContent::LiveViewContentInner::PROGRESS);
563         return true;
564     }
565 
GetNotificationLocalLiveViewTime(CNotificationSystemLiveViewContent* contentResult, std::shared_ptr<NotificationLocalLiveViewContent> &content)566     bool GetNotificationLocalLiveViewTime(CNotificationSystemLiveViewContent* contentResult,
567         std::shared_ptr<NotificationLocalLiveViewContent> &content)
568     {
569         NotificationTime time;
570         if (contentResult->time.initialTime < 0) {
571             return false;
572         }
573         time.SetInitialTime(contentResult->time.initialTime);
574         content->addFlag(NotificationLocalLiveViewContent::LiveViewContentInner::INITIAL_TIME);
575         time.SetIsCountDown(contentResult->time.isCountDown);
576         time.SetIsPaused(contentResult->time.isPaused);
577         time.SetIsInTitle(contentResult->time.isInTitle);
578 
579         content->SetTime(time);
580         content->addFlag(NotificationLocalLiveViewContent::LiveViewContentInner::TIME);
581 
582         return true;
583     }
584 
GetNotificationLocalLiveViewContentDetailed(CNotificationSystemLiveViewContent* contentResult, std::shared_ptr<NotificationLocalLiveViewContent> &content)585     bool GetNotificationLocalLiveViewContentDetailed(CNotificationSystemLiveViewContent* contentResult,
586         std::shared_ptr<NotificationLocalLiveViewContent> &content)
587     {
588         // title, text
589         std::shared_ptr<CNotificationBasicContent> tempContent = std::make_shared<CNotificationBasicContent>();
590         tempContent->title = contentResult->title;
591         tempContent->text = contentResult->text;
592         tempContent->additionalText = contentResult->additionalText;
593         tempContent->lockscreenPicture = contentResult->lockscreenPicture;
594         if (!GetNotificationBasicContentDetailed(tempContent.get(), content)) {
595             LOGE("Basic content get fail.");
596             return false;
597         }
598 
599         // typeCode
600         content->SetType(contentResult->typeCode);
601 
602         // capsule?
603         if (!GetNotificationLocalLiveViewCapsule(contentResult, content)) {
604             LOGE("GetNotificationLocalLiveViewCapsule fail.");
605             return false;
606         }
607 
608         // button?
609         if (!GetNotificationLocalLiveViewButton(contentResult, content)) {
610             LOGE("GetNotificationLocalLiveViewButton fail.");
611             return false;
612         }
613 
614         // progress?
615         if (!GetNotificationLocalLiveViewProgress(contentResult, content)) {
616             LOGE("GetNotificationLocalLiveViewProgress fail.");
617             return false;
618         }
619 
620         // time?
621         if (!GetNotificationLocalLiveViewTime(contentResult, content)) {
622             LOGE("GetNotificationLocalLiveViewTime fail.");
623             return false;
624         }
625 
626         return true;
627     }
628 
GetNotificationLocalLiveViewContent(CNotificationSystemLiveViewContent* contentResult, NotificationRequest &request)629     bool GetNotificationLocalLiveViewContent(CNotificationSystemLiveViewContent* contentResult,
630         NotificationRequest &request)
631     {
632         std::shared_ptr<NotificationLocalLiveViewContent> localLiveViewContent =
633             std::make_shared<NotificationLocalLiveViewContent>();
634         if (localLiveViewContent == nullptr) {
635             LOGE("localLiveViewContent is null");
636             return false;
637         }
638 
639         if (!GetNotificationLocalLiveViewContentDetailed(contentResult, localLiveViewContent)) {
640             return false;
641         }
642 
643         request.SetContent(std::make_shared<NotificationContent>(localLiveViewContent));
644 
645         // set isOnGoing of live view true
646         request.SetInProgress(true);
647         return true;
648     }
649 
SlotTypeCJToC(const SlotType &inType, NotificationConstant::SlotType &outType)650     bool SlotTypeCJToC(const SlotType &inType, NotificationConstant::SlotType &outType)
651     {
652         switch (inType) {
653             case SlotType::SOCIAL_COMMUNICATION:
654                 outType = NotificationConstant::SlotType::SOCIAL_COMMUNICATION;
655                 break;
656             case SlotType::SERVICE_INFORMATION:
657                 outType = NotificationConstant::SlotType::SERVICE_REMINDER;
658                 break;
659             case SlotType::CONTENT_INFORMATION:
660                 outType = NotificationConstant::SlotType::CONTENT_INFORMATION;
661                 break;
662             case SlotType::LIVE_VIEW:
663                 outType = NotificationConstant::SlotType::LIVE_VIEW;
664                 break;
665             case SlotType::CUSTOMER_SERVICE:
666                 outType = NotificationConstant::SlotType::CUSTOMER_SERVICE;
667                 break;
668             case SlotType::UNKNOWN_TYPE:
669             case SlotType::OTHER_TYPES:
670                 outType = NotificationConstant::SlotType::OTHER;
671                 break;
672             default:
673                 LOGE("SlotType %{public}d is an invalid value", inType);
674                 return false;
675         }
676         return true;
677     }
678 
SlotTypeCToCJ(const NotificationConstant::SlotType &inType, SlotType &outType)679     bool SlotTypeCToCJ(const NotificationConstant::SlotType &inType, SlotType &outType)
680     {
681         switch (inType) {
682             case NotificationConstant::SlotType::CUSTOM:
683                 outType = SlotType::UNKNOWN_TYPE;
684                 break;
685             case NotificationConstant::SlotType::SOCIAL_COMMUNICATION:
686                 outType = SlotType::SOCIAL_COMMUNICATION;
687                 break;
688             case NotificationConstant::SlotType::SERVICE_REMINDER:
689                 outType = SlotType::SERVICE_INFORMATION;
690                 break;
691             case NotificationConstant::SlotType::CONTENT_INFORMATION:
692                 outType = SlotType::CONTENT_INFORMATION;
693                 break;
694             case NotificationConstant::SlotType::LIVE_VIEW:
695                 outType = SlotType::LIVE_VIEW;
696                 break;
697             case NotificationConstant::SlotType::CUSTOMER_SERVICE:
698                 outType = SlotType::CUSTOMER_SERVICE;
699                 break;
700             case NotificationConstant::SlotType::OTHER:
701                 outType = SlotType::OTHER_TYPES;
702                 break;
703             default:
704                 LOGE("SlotType %{public}d is an invalid value", inType);
705                 return false;
706         }
707         return true;
708     }
709 
SlotLevelCToCJ(const NotificationSlot::NotificationLevel &inLevel, SlotLevel &outLevel)710     bool SlotLevelCToCJ(const NotificationSlot::NotificationLevel &inLevel, SlotLevel &outLevel)
711     {
712         switch (inLevel) {
713             case NotificationSlot::NotificationLevel::LEVEL_NONE:
714             case NotificationSlot::NotificationLevel::LEVEL_UNDEFINED:
715                 outLevel = SlotLevel::LEVEL_NONE;
716                 break;
717             case NotificationSlot::NotificationLevel::LEVEL_MIN:
718                 outLevel = SlotLevel::LEVEL_MIN;
719                 break;
720             case NotificationSlot::NotificationLevel::LEVEL_LOW:
721                 outLevel = SlotLevel::LEVEL_LOW;
722                 break;
723             case NotificationSlot::NotificationLevel::LEVEL_DEFAULT:
724                 outLevel = SlotLevel::LEVEL_DEFAULT;
725                 break;
726             case NotificationSlot::NotificationLevel::LEVEL_HIGH:
727                 outLevel = SlotLevel::LEVEL_HIGH;
728                 break;
729             default:
730                 LOGE("SlotLevel %{public}d is an invalid value", inLevel);
731                 return false;
732         }
733         return true;
734     }
735 
ContentTypeCJToC(const ContentType &inType, NotificationContent::Type &outType)736     bool ContentTypeCJToC(const ContentType &inType, NotificationContent::Type &outType)
737     {
738         switch (inType) {
739             case ContentType::NOTIFICATION_CONTENT_BASIC_TEXT:
740                 outType = NotificationContent::Type::BASIC_TEXT;
741                 break;
742             case ContentType::NOTIFICATION_CONTENT_LONG_TEXT:
743                 outType = NotificationContent::Type::LONG_TEXT;
744                 break;
745             case ContentType::NOTIFICATION_CONTENT_MULTILINE:
746                 outType = NotificationContent::Type::MULTILINE;
747                 break;
748             case ContentType::NOTIFICATION_CONTENT_PICTURE:
749                 outType = NotificationContent::Type::PICTURE;
750                 break;
751             case ContentType::NOTIFICATION_CONTENT_CONVERSATION:
752                 outType = NotificationContent::Type::CONVERSATION;
753                 break;
754             case ContentType::NOTIFICATION_CONTENT_LOCAL_LIVE_VIEW:
755                 outType = NotificationContent::Type::LOCAL_LIVE_VIEW;
756                 break;
757             case ContentType::NOTIFICATION_CONTENT_LIVE_VIEW:
758                 outType = NotificationContent::Type::LIVE_VIEW;
759                 break;
760             default:
761                 LOGE("ContentType %{public}d is an invalid value", inType);
762                 return false;
763         }
764         return true;
765     }
766 
ContentTypeCToCJ(const NotificationContent::Type &inType, ContentType &outType)767     bool ContentTypeCToCJ(const NotificationContent::Type &inType, ContentType &outType)
768     {
769         switch (inType) {
770             case NotificationContent::Type::BASIC_TEXT:
771                 outType = ContentType::NOTIFICATION_CONTENT_BASIC_TEXT;
772                 break;
773             case NotificationContent::Type::LONG_TEXT:
774                 outType = ContentType::NOTIFICATION_CONTENT_LONG_TEXT;
775                 break;
776             case NotificationContent::Type::MULTILINE:
777                 outType = ContentType::NOTIFICATION_CONTENT_MULTILINE;
778                 break;
779             case NotificationContent::Type::PICTURE:
780                 outType = ContentType::NOTIFICATION_CONTENT_PICTURE;
781                 break;
782             case NotificationContent::Type::CONVERSATION:
783                 outType = ContentType::NOTIFICATION_CONTENT_CONVERSATION;
784                 break;
785             case NotificationContent::Type::LOCAL_LIVE_VIEW:
786                 outType = ContentType::NOTIFICATION_CONTENT_LOCAL_LIVE_VIEW;
787                 break;
788             case NotificationContent::Type::LIVE_VIEW:
789                 outType = ContentType::NOTIFICATION_CONTENT_LIVE_VIEW;
790                 break;
791             default:
792                 LOGE("ContentType %{public}d is an invalid value", inType);
793                 return false;
794         }
795         return true;
796     }
797 
GetNotificationSlotType(int32_t slotType, NotificationRequest &request)798     bool GetNotificationSlotType(int32_t slotType, NotificationRequest &request)
799     {
800         NotificationConstant::SlotType outType = NotificationConstant::SlotType::OTHER;
801         if (!SlotTypeCJToC(SlotType(slotType), outType)) {
802             return false;
803         }
804         request.SetSlotType(outType);
805         return true;
806     }
807 
GetNotificationSmallIcon(int64_t smallIcon, NotificationRequest &request)808     bool GetNotificationSmallIcon(int64_t smallIcon, NotificationRequest &request)
809     {
810         if (smallIcon != -1) {
811             auto pixelMap = FFIData::GetData<Media::PixelMapImpl>(smallIcon);
812             if (pixelMap == nullptr) {
813                 LOGE("Invalid object pixelMap");
814                 return false;
815             }
816             request.SetLittleIcon(pixelMap->GetRealPixelMap());
817         }
818         return true;
819     }
820 
GetNotificationLargeIcon(int64_t largeIcon, NotificationRequest &request)821     bool GetNotificationLargeIcon(int64_t largeIcon, NotificationRequest &request)
822     {
823         if (largeIcon != -1) {
824             auto pixelMap = FFI::FFIData::GetData<Media::PixelMapImpl>(largeIcon);
825             if (pixelMap == nullptr) {
826                 LOGE("Invalid object pixelMap");
827                 return false;
828             }
829             request.SetBigIcon(pixelMap->GetRealPixelMap());
830         }
831         return true;
832     }
833 
GetNotificationContent(CNotificationContent &content, NotificationRequest &request)834     bool GetNotificationContent(CNotificationContent &content, NotificationRequest &request)
835     {
836         NotificationContent::Type outType = NotificationContent::Type::NONE;
837         if (!ContentTypeCJToC(ContentType(content.notificationContentType), outType)) {
838             return false;
839         }
840         switch (outType) {
841             case NotificationContent::Type::BASIC_TEXT:
842                 if (content.normal == nullptr || !GetNotificationBasicContent(content.normal, request)) {
843                     return false;
844                 }
845                 break;
846             case NotificationContent::Type::LONG_TEXT:
847                 if (content.longText == nullptr || !GetNotificationLongTextContent(content.longText, request)) {
848                     return false;
849                 }
850                 break;
851             case NotificationContent::Type::PICTURE:
852                 if (content.picture == nullptr || !GetNotificationPictureContent(content.picture, request)) {
853                     return false;
854                 }
855                 break;
856             case NotificationContent::Type::CONVERSATION:
857                 break;
858             case NotificationContent::Type::MULTILINE:
859                 if (content.multiLine == nullptr || !GetNotificationMultiLineContent(content.multiLine, request)) {
860                     return false;
861                 }
862                 break;
863             case NotificationContent::Type::LOCAL_LIVE_VIEW:
864                 if (content.systemLiveView == nullptr ||
865                     !GetNotificationLocalLiveViewContent(content.systemLiveView, request)) {
866                     return false;
867                 }
868                 break;
869             case NotificationContent::Type::LIVE_VIEW:
870                 break;
871             default:
872                 return false;
873         }
874         return true;
875     }
876 
SetNotificationSlot(const NotificationSlot &slot, CNotificationSlot &notificationSlot)877     bool SetNotificationSlot(const NotificationSlot &slot, CNotificationSlot &notificationSlot)
878     {
879         // type: SlotType
880         SlotType outType = SlotType::UNKNOWN_TYPE;
881         if (!SlotTypeCToCJ(slot.GetType(), outType)) {
882             LOGE("SetNotificationSlot SlotTypeCToCJ failed.");
883             return false;
884         }
885         // level?: int32_t
886         SlotLevel outLevel = SlotLevel::LEVEL_NONE;
887         if (!SlotLevelCToCJ(slot.GetLevel(), outLevel)) {
888             LOGE("SetNotificationSlot SlotLevelCToCJ failed.");
889             return false;
890         }
891         notificationSlot.notificationType = static_cast<int32_t>(outType);
892         notificationSlot.level = static_cast<int32_t>(outLevel);
893 
894         notificationSlot.desc = MallocCString(slot.GetDescription()); // desc?: string
895         notificationSlot.badgeFlag = slot.IsShowBadge(); // badgeFlag?: bool
896         notificationSlot.bypassDnd = slot.IsEnableBypassDnd(); // bypassDnd?: bool
897         // lockscreenVisibility?: int32_t
898         notificationSlot.lockscreenVisibility = static_cast<int32_t>(slot.GetLockScreenVisibleness());
899         notificationSlot.vibrationEnabled = slot.CanVibrate(); // vibrationEnabled?: bool
900         notificationSlot.sound = MallocCString(slot.GetSound().ToString()); // sound?: string
901         notificationSlot.lightEnabled = slot.CanEnableLight(); // lightEnabled?: bool
902         notificationSlot.lightColor = slot.GetLedLightColor(); // lightColor?: int32_t
903 
904         // vibrationValues?: Array<int64_t>
905         auto vec = slot.GetVibrationStyle();
906         CArrI64 vibrationValues = { .head = NULL, .size = 0 };
907         vibrationValues.size = static_cast<int64_t>(vec.size());
908         if (vibrationValues.size > 0) {
909             int64_t* head = static_cast<int64_t *>(malloc(sizeof(int64_t) * vec.size()));
910             if (head == nullptr) {
911                 free(notificationSlot.desc);
912                 free(notificationSlot.sound);
913                 notificationSlot.desc = nullptr;
914                 notificationSlot.sound = nullptr;
915                 LOGE("SetNotificationSlot malloc vibrationValues.head failed.");
916                 return false;
917             }
918             int i = 0;
919             for (auto value : vec) {
920                 head[i++] = static_cast<int64_t>(value);
921             }
922             vibrationValues.head = head;
923         }
924         notificationSlot.vibrationValues = vibrationValues;
925         notificationSlot.enabled = slot.GetEnable(); // enabled?: boolean
926         return true;
927     }
928 
SetNotificationRequestByString( const NotificationRequest *request, CNotificationRequest &notificationRequest)929     void SetNotificationRequestByString(
930         const NotificationRequest *request,
931         CNotificationRequest &notificationRequest)
932     {
933         // label?: string
934         notificationRequest.label = MallocCString(request->GetLabel());
935 
936         // groupName?: string
937         notificationRequest.groupName = MallocCString(request->GetGroupName());
938 
939         // readonly creatorBundleName?: string
940         notificationRequest.creatorBundleName = MallocCString(request->GetCreatorBundleName());
941     }
942 
SetNotificationRequestByNumber( const NotificationRequest *request, CNotificationRequest &notificationRequest)943     bool SetNotificationRequestByNumber(
944         const NotificationRequest *request,
945         CNotificationRequest &notificationRequest)
946     {
947         // id?: int32_t
948         notificationRequest.id = request->GetNotificationId();
949 
950         // slotType?: SlotType
951         SlotType outType = SlotType::UNKNOWN_TYPE;
952         if (!SlotTypeCToCJ(request->GetSlotType(), outType)) {
953             return false;
954         }
955         notificationRequest.notificationSlotType = static_cast<int32_t>(outType);
956 
957         // deliveryTime?: int32_t
958         notificationRequest.deliveryTime = request->GetDeliveryTime();
959 
960         // autoDeletedTime?: int32_t
961         notificationRequest.autoDeletedTime = request->GetAutoDeletedTime();
962 
963         // color ?: int32_t
964         notificationRequest.color = request->GetColor();
965 
966         // badgeIconStyle ?: int32_t
967         notificationRequest.badgeIconStyle = static_cast<int32_t>(request->GetBadgeIconStyle());
968 
969         // readonly creatorUid?: int32_t
970         notificationRequest.creatorUid = request->GetCreatorUid();
971 
972         // readonly creatorPid?: int32_t
973         notificationRequest.creatorPid = request->GetCreatorPid();
974 
975         // badgeNumber?: uint32_t
976         notificationRequest.badgeNumber = request->GetBadgeNumber();
977 
978         return true;
979     }
980 
SetNotificationRequestByBool( const NotificationRequest *request, CNotificationRequest &notificationRequest)981     void SetNotificationRequestByBool(
982         const NotificationRequest *request,
983         CNotificationRequest &notificationRequest)
984     {
985         // isOngoing?: boolean
986         notificationRequest.isOngoing = request->IsInProgress();
987 
988         // isUnremovable?: boolean
989         notificationRequest.isUnremovable = request->IsUnremovable();
990 
991         // tapDismissed?: boolean
992         notificationRequest.tapDismissed = request->IsTapDismissed();
993 
994         // colorEnabled?: boolean
995         notificationRequest.colorEnabled = request->IsColorEnabled();
996 
997         // isAlertOnce?: boolean
998         notificationRequest.isAlertOnce = request->IsAlertOneTime();
999 
1000         // isStopwatch?: boolean
1001         notificationRequest.isStopwatch = request->IsShowStopwatch();
1002 
1003         // isCountDown?: boolean
1004         notificationRequest.isCountDown = request->IsCountdownTimer();
1005 
1006         // isFloatingIcon?: boolean
1007         notificationRequest.isFloatingIcon = request->IsFloatingIcon();
1008 
1009         // showDeliveryTime?: boolean
1010         notificationRequest.showDeliveryTime = request->IsShowDeliveryTime();
1011     }
1012 
SetNotificationRequestByPixelMap( const NotificationRequest *request, CNotificationRequest &notificationRequest)1013     void SetNotificationRequestByPixelMap(
1014         const NotificationRequest *request,
1015         CNotificationRequest &notificationRequest)
1016     {
1017         // smallIcon?: image.PixelMap
1018         std::shared_ptr<Media::PixelMap> littleIcon = request->GetLittleIcon();
1019         notificationRequest.smallIcon = -1;
1020         if (littleIcon) {
1021             auto native = FFIData::Create<Media::PixelMapImpl>(littleIcon);
1022             if (native != nullptr) {
1023                 notificationRequest.smallIcon = native->GetID();
1024             }
1025         }
1026 
1027         // largeIcon?: image.PixelMap
1028         notificationRequest.largeIcon = -1;
1029         std::shared_ptr<Media::PixelMap> largeIcon = request->GetBigIcon();
1030         if (largeIcon) {
1031             auto native = FFIData::Create<Media::PixelMapImpl>(largeIcon);
1032             if (native != nullptr) {
1033                 notificationRequest.largeIcon = native->GetID();
1034             }
1035         }
1036     }
1037 
freeNotificationBasicContent(CNotificationBasicContent* normal)1038     static void freeNotificationBasicContent(CNotificationBasicContent* normal)
1039     {
1040         free(normal->title);
1041         free(normal->text);
1042         free(normal->additionalText);
1043         normal->title = nullptr;
1044         normal->text = nullptr;
1045         normal->additionalText = nullptr;
1046     }
1047 
SetNotificationBasicContent( const NotificationBasicContent *basicContent, CNotificationBasicContent* normal)1048     bool SetNotificationBasicContent(
1049         const NotificationBasicContent *basicContent,
1050         CNotificationBasicContent* normal)
1051     {
1052         if (basicContent == nullptr || normal == nullptr) {
1053             return false;
1054         }
1055 
1056         // title: string
1057         normal->title = MallocCString(basicContent->GetTitle());
1058 
1059         // text: string
1060         normal->text = MallocCString(basicContent->GetText());
1061 
1062         // additionalText?: string
1063         normal->additionalText = MallocCString(basicContent->GetAdditionalText());
1064 
1065         // lockScreenPicture?: pixelMap
1066         normal->lockscreenPicture = -1;
1067         if (basicContent->GetLockScreenPicture()) {
1068             std::shared_ptr<Media::PixelMap> pix = basicContent->GetLockScreenPicture();
1069             if (pix == nullptr) {
1070                 LOGE("Invalid object pixelMap");
1071                 freeNotificationBasicContent(normal);
1072                 return false;
1073             }
1074             auto native = FFIData::Create<Media::PixelMapImpl>(pix);
1075             if (native == nullptr) {
1076                 LOGE("Invalid object pixelMap");
1077                 freeNotificationBasicContent(normal);
1078                 return false;
1079             }
1080             normal->lockscreenPicture = native->GetID();
1081         }
1082         return true;
1083     }
1084 
freeNotificationLongTextContent(CNotificationLongTextContent* longText)1085     static void freeNotificationLongTextContent(CNotificationLongTextContent* longText)
1086     {
1087         free(longText->title);
1088         free(longText->text);
1089         free(longText->additionalText);
1090         free(longText->longText);
1091         free(longText->briefText);
1092         free(longText->expandedTitle);
1093         longText->title = nullptr;
1094         longText->text = nullptr;
1095         longText->additionalText = nullptr;
1096         longText->longText = nullptr;
1097         longText->briefText = nullptr;
1098         longText->expandedTitle = nullptr;
1099     }
1100 
SetNotificationLongTextContent( NotificationBasicContent *basicContent, CNotificationLongTextContent* longText)1101     bool SetNotificationLongTextContent(
1102         NotificationBasicContent *basicContent,
1103         CNotificationLongTextContent* longText)
1104     {
1105         if (basicContent == nullptr) {
1106             LOGE("basicContent is null.");
1107             return false;
1108         }
1109         if (longText == nullptr) {
1110             LOGE("malloc CNotificationLongTextContent failed, longText is null.");
1111             return false;
1112         }
1113 
1114         OHOS::Notification::NotificationLongTextContent *longTextContent =
1115             static_cast<OHOS::Notification::NotificationLongTextContent *>(basicContent);
1116         if (longTextContent == nullptr) {
1117             LOGE("longTextContent is null");
1118             return false;
1119         }
1120         // title: string
1121         longText->title = MallocCString(longTextContent->GetTitle());
1122         // text: string
1123         longText->text = MallocCString(longTextContent->GetText());
1124         // additionalText?: string
1125         longText->additionalText = MallocCString(longTextContent->GetAdditionalText());
1126         // longText: string
1127         longText->longText = MallocCString(longTextContent->GetLongText());
1128         // briefText: string
1129         longText->briefText = MallocCString(longTextContent->GetBriefText());
1130         // expandedTitle: string
1131         longText->expandedTitle = MallocCString(longTextContent->GetExpandedTitle());
1132         // lockScreenPicture?: pixelMap
1133         longText->lockscreenPicture = -1;
1134         if (longTextContent->GetLockScreenPicture()) {
1135             std::shared_ptr<Media::PixelMap> pix = longTextContent->GetLockScreenPicture();
1136             if (pix == nullptr) {
1137                 LOGE("Invalid object pixelMap");
1138                 freeNotificationLongTextContent(longText);
1139                 return false;
1140             }
1141             auto native = FFIData::Create<Media::PixelMapImpl>(pix);
1142             if (native == nullptr) {
1143                 LOGE("Invalid object pixelMap");
1144                 freeNotificationLongTextContent(longText);
1145                 return false;
1146             }
1147             longText->lockscreenPicture = native->GetID();
1148         }
1149         return true;
1150     }
1151 
freeNotificationPictureContent(CNotificationPictureContent* picture)1152     static void freeNotificationPictureContent(CNotificationPictureContent* picture)
1153     {
1154         free(picture->title);
1155         free(picture->text);
1156         free(picture->additionalText);
1157         free(picture->briefText);
1158         free(picture->expandedTitle);
1159         picture->title = nullptr;
1160         picture->text = nullptr;
1161         picture->additionalText = nullptr;
1162         picture->briefText = nullptr;
1163         picture->expandedTitle = nullptr;
1164     }
1165 
SetNotificationPictureContent(NotificationBasicContent *basicContent, CNotificationPictureContent* picture)1166     bool SetNotificationPictureContent(NotificationBasicContent *basicContent,
1167         CNotificationPictureContent* picture)
1168     {
1169         if (basicContent == nullptr) {
1170             LOGE("basicContent is null");
1171             return false;
1172         }
1173         OHOS::Notification::NotificationPictureContent *pictureContent =
1174             static_cast<OHOS::Notification::NotificationPictureContent *>(basicContent);
1175         if (pictureContent == nullptr) {
1176             LOGE("pictureContent is null");
1177             return false;
1178         }
1179         // title、text: string
1180         picture->title = MallocCString(pictureContent->GetTitle());
1181         picture->text = MallocCString(pictureContent->GetText());
1182         // additionalText?: string
1183         picture->additionalText = MallocCString(pictureContent->GetAdditionalText());
1184         // briefText、expandedTitle: string
1185         picture->briefText = MallocCString(pictureContent->GetBriefText());
1186         picture->expandedTitle = MallocCString(pictureContent->GetExpandedTitle());
1187         // picture: image.PixelMap
1188         std::shared_ptr<Media::PixelMap> pix = pictureContent->GetBigPicture();
1189         if (pix == nullptr) {
1190             LOGE("Invalid object pixelMap");
1191             freeNotificationPictureContent(picture);
1192             return false;
1193         }
1194         auto native1 = FFIData::Create<Media::PixelMapImpl>(pix);
1195         if (native1 == nullptr) {
1196             LOGE("Invalid object pixelMap");
1197             freeNotificationPictureContent(picture);
1198             return false;
1199         }
1200         picture->picture = native1->GetID();
1201         // lockScreenPicture?: pixelMap
1202         picture->lockscreenPicture = -1;
1203         if (pictureContent->GetLockScreenPicture()) {
1204             std::shared_ptr<Media::PixelMap> pixx = pictureContent->GetLockScreenPicture();
1205             if (pixx == nullptr) {
1206                 LOGE("Invalid object pixelMap");
1207                 freeNotificationPictureContent(picture);
1208                 return false;
1209             }
1210             auto native2 = FFIData::Create<Media::PixelMapImpl>(pixx);
1211             if (native2 == nullptr) {
1212                 LOGE("Invalid object pixelMap");
1213                 freeNotificationPictureContent(picture);
1214                 return false;
1215             }
1216             picture->lockscreenPicture = native2->GetID();
1217         }
1218         return true;
1219     }
1220 
freeNotificationMultiLineContent(CNotificationMultiLineContent* multiLine)1221     static void freeNotificationMultiLineContent(CNotificationMultiLineContent* multiLine)
1222     {
1223         free(multiLine->title);
1224         free(multiLine->text);
1225         free(multiLine->additionalText);
1226         free(multiLine->briefText);
1227         free(multiLine->longTitle);
1228         if (multiLine->lines.head != nullptr) {
1229             for (int64_t i = 0; i < multiLine->lines.size; i++) {
1230                 free(multiLine->lines.head[i]);
1231             }
1232             free(multiLine->lines.head);
1233             multiLine->lines.head = nullptr;
1234         }
1235         multiLine->title = nullptr;
1236         multiLine->text = nullptr;
1237         multiLine->additionalText = nullptr;
1238         multiLine->briefText = nullptr;
1239         multiLine->longTitle = nullptr;
1240     }
1241 
SetNotificationMultiLineContent( NotificationBasicContent *basicContent, CNotificationMultiLineContent* multiLine)1242     bool SetNotificationMultiLineContent(
1243         NotificationBasicContent *basicContent,
1244         CNotificationMultiLineContent* multiLine)
1245     {
1246         if (basicContent == nullptr) {
1247             LOGE("basicContent is null");
1248             return false;
1249         }
1250         OHOS::Notification::NotificationMultiLineContent *multiLineContent =
1251             static_cast<OHOS::Notification::NotificationMultiLineContent *>(basicContent);
1252         if (multiLineContent == nullptr) {
1253             LOGE("multiLineContent is null");
1254             return false;
1255         }
1256         // title、text、additionalText?: string
1257         multiLine->title = MallocCString(multiLineContent->GetTitle());
1258         multiLine->text = MallocCString(multiLineContent->GetText());
1259         multiLine->additionalText = MallocCString(multiLineContent->GetAdditionalText());
1260         // briefText、longTitle: string
1261         multiLine->briefText = MallocCString(multiLineContent->GetBriefText());
1262         multiLine->longTitle = MallocCString(multiLineContent->GetExpandedTitle());
1263         // lines: Array<String>
1264         auto vecs = multiLineContent->GetAllLines();
1265         CArrString lines = { .head = nullptr, .size = 0 };
1266         lines.head = static_cast<char **>(malloc(sizeof(char *) * vecs.size()));
1267         lines.size = static_cast<int64_t>(vecs.size());
1268         if (lines.head == nullptr) {
1269             LOGE("multiLineContent lines malloc failed");
1270             freeNotificationMultiLineContent(multiLine);
1271             return false;
1272         }
1273         int i = 0 ;
1274         for (auto vec : vecs) {
1275             lines.head[i++] = MallocCString(vec);
1276         }
1277         multiLine->lines = lines;
1278         // lockScreenPicture?: pixelMap
1279         multiLine->lockscreenPicture = -1;
1280         if (multiLineContent->GetLockScreenPicture()) {
1281             std::shared_ptr<Media::PixelMap> pix = multiLineContent->GetLockScreenPicture();
1282             if (pix == nullptr) {
1283                 LOGE("Invalid object pixelMap");
1284                 freeNotificationMultiLineContent(multiLine);
1285                 return false;
1286             }
1287             auto native2 = FFIData::Create<Media::PixelMapImpl>(pix);
1288             if (native2 == nullptr) {
1289                 LOGE("Invalid object pixelMap");
1290                 freeNotificationMultiLineContent(multiLine);
1291                 return false;
1292             }
1293             multiLine->lockscreenPicture = native2->GetID();
1294         }
1295         return true;
1296     }
1297 
SetCapsule(const NotificationCapsule &capsule, CNotificationCapsule &cCapsule)1298     bool SetCapsule(const NotificationCapsule &capsule, CNotificationCapsule &cCapsule)
1299     {
1300         // title: string
1301         cCapsule.title = MallocCString(capsule.GetTitle());
1302         // backgroundColor: string
1303         cCapsule.backgroundColor = MallocCString(capsule.GetBackgroundColor());
1304         // icon?: image.PixelMap
1305         std::shared_ptr<Media::PixelMap> icon = capsule.GetIcon();
1306         if (icon) {
1307             auto native = FFIData::Create<Media::PixelMapImpl>(icon);
1308             if (native == nullptr) {
1309                 free(cCapsule.title);
1310                 free(cCapsule.backgroundColor);
1311                 cCapsule.title = nullptr;
1312                 cCapsule.backgroundColor = nullptr;
1313                 LOGE("Invalid object pixelMap of icon");
1314                 return false;
1315             }
1316             cCapsule.icon = native->GetID();
1317         }
1318         return true;
1319     }
1320 
SetButton(const NotificationLocalLiveViewButton &button, CNotificationButton &cButton)1321     bool SetButton(const NotificationLocalLiveViewButton &button, CNotificationButton &cButton)
1322     {
1323         // buttonNames: Array<String>
1324         auto vecs = button.GetAllButtonNames();
1325         CArrString names = { .head = nullptr, .size = 0 };
1326         names.head = static_cast<char **>(malloc(sizeof(char *) * vecs.size()));
1327         names.size = static_cast<int64_t>(vecs.size());
1328         if (names.head == nullptr) {
1329             LOGE("NotificationButton names malloc failed");
1330             return false;
1331         }
1332         int i = 0;
1333         for (auto vec : vecs) {
1334             names.head[i++] = MallocCString(vec);
1335         }
1336         cButton.names = names;
1337 
1338         // buttonIcons: Array<PixelMap>
1339         int iconCount = 0;
1340         std::vector<std::shared_ptr<Media::PixelMap>> iconsVec = button.GetAllButtonIcons();
1341         CArrI64 icons = { .head = nullptr, .size = iconsVec.size() };
1342         for (auto vec : iconsVec) {
1343             if (!vec) {
1344                 continue;
1345             }
1346             // buttonIcon
1347             auto native = FFIData::Create<Media::PixelMapImpl>(vec);
1348             if (native == nullptr) {
1349                 LOGE("Invalid object pixelMap of buttonIcons.");
1350                 return false; // memory free at cj
1351             }
1352             icons.head[iconCount++] = native->GetID();
1353         }
1354         cButton.icons = icons;
1355         return true;
1356     }
1357 
SetNotificationLocalLiveViewContentDetailed(NotificationLocalLiveViewContent *localLiveViewContent, CNotificationSystemLiveViewContent* systemLiveView)1358     bool SetNotificationLocalLiveViewContentDetailed(NotificationLocalLiveViewContent *localLiveViewContent,
1359         CNotificationSystemLiveViewContent* systemLiveView)
1360     {
1361         // capsule: NotificationCapsule
1362         CNotificationCapsule capsule = {
1363             .title = nullptr,
1364             .icon = -1,
1365             .backgroundColor = nullptr
1366         };
1367         if (localLiveViewContent->isFlagExist(NotificationLocalLiveViewContent::LiveViewContentInner::CAPSULE)) {
1368             if (!SetCapsule(localLiveViewContent->GetCapsule(), capsule)) {
1369                 LOGE("SetCapsule call failed");
1370                 return false;
1371             }
1372         }
1373         systemLiveView->capsule = capsule;
1374 
1375         // button: NotificationLocalLiveViewButton
1376         CNotificationButton cButton = {
1377             .names = { .head = nullptr, .size = 0 },
1378             .icons = { .head = nullptr, .size = 0 }
1379         };
1380         if (localLiveViewContent->isFlagExist(NotificationLocalLiveViewContent::LiveViewContentInner::BUTTON)) {
1381             if (!SetButton(localLiveViewContent->GetButton(), cButton)) {
1382                 LOGE("SetButton call failed");
1383                 return false;
1384             }
1385         }
1386         systemLiveView->button = cButton;
1387 
1388         // progress: NotificationProgress
1389         CNotificationProgress cProgress;
1390         if (localLiveViewContent->isFlagExist(NotificationLocalLiveViewContent::LiveViewContentInner::PROGRESS)) {
1391             NotificationProgress progress = localLiveViewContent->GetProgress();
1392             cProgress.maxValue = progress.GetMaxValue();
1393             cProgress.currentValue = progress.GetCurrentValue();
1394             cProgress.isPercentage = progress.GetIsPercentage();
1395         }
1396         systemLiveView->progress = cProgress;
1397 
1398         // time: NotificationTime
1399         CNotificationTime cTime;
1400         if (localLiveViewContent->isFlagExist(NotificationLocalLiveViewContent::LiveViewContentInner::TIME)) {
1401             NotificationTime time = localLiveViewContent->GetTime();
1402             bool flag = localLiveViewContent->isFlagExist(
1403                 NotificationLocalLiveViewContent::LiveViewContentInner::INITIAL_TIME);
1404             cTime.initialTime = flag ? time.GetInitialTime() : 0;
1405             cTime.isCountDown = time.GetIsCountDown();
1406             cTime.isPaused = time.GetIsPaused();
1407             cTime.isInTitle = time.GetIsInTitle();
1408         }
1409         systemLiveView->time = cTime;
1410 
1411         return true;
1412     }
1413 
SetNotificationLocalLiveViewContent(NotificationBasicContent *basicContent, CNotificationSystemLiveViewContent* systemLiveView)1414     bool SetNotificationLocalLiveViewContent(NotificationBasicContent *basicContent,
1415         CNotificationSystemLiveViewContent* systemLiveView)
1416     {
1417         if (basicContent == nullptr) {
1418             LOGE("basicContent is null.");
1419             return false;
1420         }
1421         if (systemLiveView == nullptr) {
1422             LOGE("malloc CNotificationSystemLiveViewContent failed, systemLiveView is null");
1423             return false;
1424         }
1425         OHOS::Notification::NotificationLocalLiveViewContent *localLiveViewContent =
1426             static_cast<OHOS::Notification::NotificationLocalLiveViewContent *>(basicContent);
1427         if (localLiveViewContent == nullptr) {
1428             LOGE("localLiveViewContent is null");
1429             return false;
1430         }
1431 
1432         // title, text, additionalText?
1433         systemLiveView->title = MallocCString(localLiveViewContent->GetTitle());
1434         systemLiveView->text = MallocCString(localLiveViewContent->GetText());
1435         systemLiveView->additionalText = MallocCString(localLiveViewContent->GetAdditionalText());
1436         // typeCode: int32_t
1437         systemLiveView->typeCode = localLiveViewContent->GetType();
1438 
1439         if (!SetNotificationLocalLiveViewContentDetailed(localLiveViewContent, systemLiveView)) {
1440             LOGE("SetNotificationLocalLiveViewContentDetail call failed");
1441             return false;
1442         }
1443 
1444         // lockScreenPicture?: pixelMap
1445         systemLiveView->lockscreenPicture = -1;
1446         if (localLiveViewContent->GetLockScreenPicture()) {
1447             std::shared_ptr<Media::PixelMap> pix = localLiveViewContent->GetLockScreenPicture();
1448             if (pix == nullptr) {
1449                 LOGE("Invalid object pixelMap");
1450                 return false;
1451             }
1452             auto native2 = FFIData::Create<Media::PixelMapImpl>(pix);
1453             if (native2 == nullptr) {
1454                 LOGE("Invalid object pixelMap");
1455                 return false;
1456             }
1457             systemLiveView->lockscreenPicture = native2->GetID();
1458         }
1459         return true;
1460     }
1461 
SetNotificationContentDetailed(const ContentType &type, const std::shared_ptr<NotificationContent> &content, CNotificationContent &notificationContent)1462     bool SetNotificationContentDetailed(const ContentType &type,
1463         const std::shared_ptr<NotificationContent> &content, CNotificationContent &notificationContent)
1464     {
1465         bool ret = false;
1466         std::shared_ptr<NotificationBasicContent> basicContent = content->GetNotificationContent();
1467         if (basicContent == nullptr) {
1468             LOGE("content is null");
1469             return ret;
1470         }
1471         switch (type) {
1472             case ContentType::NOTIFICATION_CONTENT_BASIC_TEXT: // normal?: NotificationBasicContent
1473                 notificationContent.normal =
1474                     static_cast<CNotificationBasicContent *>(malloc(sizeof(CNotificationBasicContent)));
1475                 ret = SetNotificationBasicContent(basicContent.get(), notificationContent.normal);
1476                 break;
1477             case ContentType::NOTIFICATION_CONTENT_LONG_TEXT: // longText?: NotificationLongTextContent
1478                 notificationContent.longText =
1479                     static_cast<CNotificationLongTextContent *>(malloc(sizeof(CNotificationLongTextContent)));
1480                 ret = SetNotificationLongTextContent(basicContent.get(), notificationContent.longText);
1481                 break;
1482             case ContentType::NOTIFICATION_CONTENT_PICTURE: // picture?: NotificationPictureContent
1483                 notificationContent.picture =
1484                     static_cast<CNotificationPictureContent *>(malloc(sizeof(CNotificationPictureContent)));
1485                 if (notificationContent.picture == nullptr) {
1486                     LOGE("SetNotificationContentDetailed malloc CNotificationPictureContent failed.");
1487                     return false;
1488                 }
1489                 ret = SetNotificationPictureContent(basicContent.get(), notificationContent.picture);
1490                 break;
1491             case ContentType::NOTIFICATION_CONTENT_MULTILINE: // multiLine?: NotificationMultiLineContent
1492                 notificationContent.multiLine =
1493                     static_cast<CNotificationMultiLineContent *>(malloc(sizeof(CNotificationMultiLineContent)));
1494                 if (notificationContent.multiLine == nullptr) {
1495                     LOGE("SetNotificationContentDetailed malloc CNotificationMultiLineContent failed.");
1496                     return false;
1497                 }
1498                 ret = SetNotificationMultiLineContent(basicContent.get(), notificationContent.multiLine);
1499                 break;
1500             case ContentType::NOTIFICATION_CONTENT_LOCAL_LIVE_VIEW: // systemLiveView?: NotificationLocalLiveViewContent
1501                 notificationContent.systemLiveView =
1502                     static_cast<CNotificationSystemLiveViewContent *>(
1503                             malloc(sizeof(CNotificationSystemLiveViewContent)));
1504                 ret = SetNotificationLocalLiveViewContent(basicContent.get(), notificationContent.systemLiveView);
1505                 break;
1506             case ContentType::NOTIFICATION_CONTENT_LIVE_VIEW: // liveView?: NotificationLiveViewContent
1507                 LOGE("ContentType::NOTIFICATION_CONTENT_LIVE_VIEW is not support");
1508             default:
1509                 LOGE("ContentType is does not exist");
1510                 return ret;
1511         }
1512         return ret;
1513     }
1514 
SetNotificationContent( const std::shared_ptr<NotificationContent> &content, CNotificationContent &notificationContent)1515     bool SetNotificationContent(
1516         const std::shared_ptr<NotificationContent> &content,
1517         CNotificationContent &notificationContent)
1518     {
1519         // contentType: ContentType
1520         NotificationContent::Type type = content->GetContentType();
1521         ContentType outType = ContentType::NOTIFICATION_CONTENT_BASIC_TEXT;
1522         if (!ContentTypeCToCJ(type, outType)) {
1523             return false;
1524         }
1525         notificationContent.notificationContentType = static_cast<int32_t>(outType);
1526         if (!SetNotificationContentDetailed(outType, content, notificationContent)) {
1527             LOGE("SetNotificationContentDetailed failed");
1528             return false;
1529         }
1530         return true;
1531     }
1532 
SetNotificationFlags( const std::shared_ptr<NotificationFlags> &flags, CNotificationFlags &notificationFlags)1533     bool SetNotificationFlags(
1534         const std::shared_ptr<NotificationFlags> &flags,
1535         CNotificationFlags &notificationFlags)
1536     {
1537         if (flags == nullptr) {
1538             LOGE("flags is null");
1539             return false;
1540         }
1541         notificationFlags.soundEnabled = static_cast<int32_t>(flags->IsSoundEnabled());
1542         notificationFlags.vibrationEnabled = static_cast<int32_t>(flags->IsVibrationEnabled());
1543         return true;
1544     }
1545 
SetNotificationRequestByCustom( const NotificationRequest *request, CNotificationRequest &notificationRequest)1546     bool SetNotificationRequestByCustom(
1547         const NotificationRequest *request,
1548         CNotificationRequest &notificationRequest)
1549     {
1550         // content: NotificationContent
1551         std::shared_ptr<NotificationContent> content = request->GetContent();
1552         if (!content) {
1553             LOGE("content is nullptr");
1554             return false;
1555         }
1556         if (!SetNotificationContent(content, notificationRequest.notificationContent)) {
1557             LOGE("SetNotificationContent call failed");
1558             return false;
1559         }
1560 
1561         // readonly notificationFlags?: NotificationFlags
1562         std::shared_ptr<NotificationFlags> flags = request->GetFlags();
1563         if (flags) {
1564             if (!SetNotificationFlags(flags, notificationRequest.notificationFlags)) {
1565                 LOGE("SetNotificationFlags call failed");
1566                 return false;
1567             }
1568         }
1569         return true;
1570     }
1571 
InitNotificationRequest(CNotificationRequest &notificationRequest)1572     static void InitNotificationRequest(CNotificationRequest &notificationRequest)
1573     {
1574         notificationRequest.notificationContent = {
1575             .notificationContentType = 0,
1576             .normal = nullptr,
1577             .longText = nullptr,
1578             .multiLine = nullptr,
1579             .picture = nullptr
1580         };
1581         notificationRequest.label = nullptr;
1582         notificationRequest.creatorBundleName = nullptr;
1583         notificationRequest.groupName = nullptr;
1584         notificationRequest.distributedOption = nullptr;
1585         notificationRequest.hashCode = nullptr;
1586         notificationRequest.appMessageId = nullptr;
1587     }
1588 
SetNotificationRequest( const NotificationRequest *request, CNotificationRequest &notificationRequest)1589     bool SetNotificationRequest(
1590         const NotificationRequest *request,
1591         CNotificationRequest &notificationRequest)
1592     {
1593         if (request == nullptr) {
1594             LOGE("request is nullptr");
1595             return false;
1596         }
1597         InitNotificationRequest(notificationRequest);
1598         SetNotificationRequestByString(request, notificationRequest);
1599         SetNotificationRequestByBool(request, notificationRequest);
1600         SetNotificationRequestByPixelMap(request, notificationRequest);
1601         if (!SetNotificationRequestByNumber(request, notificationRequest)) {
1602             LOGE("SetNotificationRequestByNumber failed");
1603             return false;
1604         }
1605         if (!SetNotificationRequestByCustom(request, notificationRequest)) {
1606             LOGE("SetNotificationRequestByCustom failed");
1607             return false;
1608         }
1609         return true;
1610     }
1611 }
1612 }
1613 }