• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <sstream>
17 
18 #include "distributed_service.h"
19 
20 #include "ability_manager_client.h"
21 #include "notification_helper.h"
22 #include "distributed_client.h"
23 #include "request_box.h"
24 #include "state_box.h"
25 #include "ans_image_util.h"
26 #include "in_process_call_wrapper.h"
27 #include "distributed_observer_service.h"
28 #include "distributed_preference.h"
29 #include "distributed_liveview_all_scenarios_extension_wrapper.h"
30 #include "response_box.h"
31 #include "power_mgr_client.h"
32 #include "distributed_local_config.h"
33 #include "distributed_operation_service.h"
34 #include "notification_sync_box.h"
35 #include "ans_inner_errors.h"
36 #include "ability_manager_helper.h"
37 #include "int_wrapper.h"
38 #include "string_wrapper.h"
39 
40 namespace OHOS {
41 namespace Notification {
42 
43 namespace {
44 const std::string DISTRIBUTED_LABEL = "ans_distributed";
45 constexpr const int32_t ANS_CUSTOMIZE_CODE = 7;
46 constexpr const int32_t MODIFY_ERROR_EVENT_CODE = 6;
47 constexpr const int32_t DELETE_ERROR_EVENT_CODE = 5;
48 constexpr const int32_t OPERATION_DELETE_BRANCH = 2;
49 constexpr const int32_t BRANCH3_ID = 3;
50 constexpr const int32_t BRANCH4_ID = 4;
51 constexpr const int32_t BRANCH6_ID = 6;
52 constexpr const int32_t BRANCH9_ID = 9;
53 }
54 
GetCurrentTime()55 int64_t GetCurrentTime()
56 {
57     auto now = std::chrono::system_clock::now();
58     auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
59     return duration.count();
60 }
61 
62 struct TransferNotification {
63     std::string title;
64     std::string context;
65     std::string additionalText;
66     std::string briefText;
67     std::string expandedTitle;
68 };
69 
ConvertBoxToLongContent(const TransferNotification & notificationItem,const NotifticationRequestBox & box,sptr<NotificationRequest> & request)70 void ConvertBoxToLongContent(const TransferNotification& notificationItem, const NotifticationRequestBox& box,
71     sptr<NotificationRequest>& request)
72 {
73     auto pContent = std::make_shared<NotificationLongTextContent>();
74     pContent->SetText(notificationItem.context);
75     pContent->SetTitle(notificationItem.title);
76     pContent->SetAdditionalText(notificationItem.additionalText);
77     pContent->SetBriefText(notificationItem.briefText);
78     pContent->SetExpandedTitle(notificationItem.expandedTitle);
79     std::string longText;
80     box.GetNotificationLongText(longText);
81     pContent->SetLongText(longText);
82     auto content = std::make_shared<NotificationContent>(pContent);
83     request->SetContent(content);
84 }
85 
ConvertBoxToMultileContent(const TransferNotification & notificationItem,const NotifticationRequestBox & box,sptr<NotificationRequest> & request)86 void ConvertBoxToMultileContent(const TransferNotification& notificationItem, const NotifticationRequestBox& box,
87     sptr<NotificationRequest>& request)
88 {
89     auto pContent = std::make_shared<NotificationMultiLineContent>();
90     pContent->SetText(notificationItem.context);
91     pContent->SetTitle(notificationItem.title);
92     pContent->SetAdditionalText(notificationItem.additionalText);
93     pContent->SetBriefText(notificationItem.briefText);
94     pContent->SetExpandedTitle(notificationItem.expandedTitle);
95     std::vector<std::string> allLines;
96     box.GetNotificationAllLines(allLines);
97     for (auto& item : allLines) {
98         pContent->AddSingleLine(item);
99     }
100     auto content = std::make_shared<NotificationContent>(pContent);
101     request->SetContent(content);
102 }
103 
ConvertBoxToPictureContent(const TransferNotification & notificationItem,const NotifticationRequestBox & box,sptr<NotificationRequest> & request)104 void ConvertBoxToPictureContent(const TransferNotification& notificationItem, const NotifticationRequestBox& box,
105     sptr<NotificationRequest>& request)
106 {
107     auto pContent = std::make_shared<NotificationPictureContent>();
108     pContent->SetText(notificationItem.context);
109     pContent->SetTitle(notificationItem.title);
110     pContent->SetAdditionalText(notificationItem.additionalText);
111     pContent->SetBriefText(notificationItem.briefText);
112     pContent->SetExpandedTitle(notificationItem.expandedTitle);
113     std::shared_ptr<Media::PixelMap> bigPicture;
114     box.GetNotificationBigPicture(bigPicture);
115     pContent->SetBigPicture(bigPicture);
116     auto content = std::make_shared<NotificationContent>(pContent);
117     request->SetContent(content);
118 }
119 
SetNotifictaionContent(const NotifticationRequestBox & box,sptr<NotificationRequest> & request,int32_t contentType)120 void DistributedService::SetNotifictaionContent(const NotifticationRequestBox& box, sptr<NotificationRequest>& request,
121     int32_t contentType)
122 {
123     TransferNotification notificationItem;
124     box.GetNotificationText(notificationItem.context);
125     box.GetNotificationTitle(notificationItem.title);
126     box.GetNotificationAdditionalText(notificationItem.additionalText);
127     NotificationContent::Type type = static_cast<NotificationContent::Type>(contentType);
128     if (type == NotificationContent::Type::LONG_TEXT || type == NotificationContent::Type::MULTILINE ||
129         type == NotificationContent::Type::PICTURE) {
130         box.GetNotificationBriefText(notificationItem.briefText);
131         box.GetNotificationExpandedTitle(notificationItem.expandedTitle);
132     }
133     switch (type) {
134         case NotificationContent::Type::BASIC_TEXT: {
135             auto pContent = std::make_shared<NotificationNormalContent>();
136             pContent->SetText(notificationItem.context);
137             pContent->SetTitle(notificationItem.title);
138             pContent->SetAdditionalText(notificationItem.additionalText);
139             auto content = std::make_shared<NotificationContent>(pContent);
140             request->SetContent(content);
141             break;
142         }
143         case NotificationContent::Type::CONVERSATION: {
144             auto pContent = std::make_shared<NotificationConversationalContent>();
145             pContent->SetText(notificationItem.context);
146             pContent->SetTitle(notificationItem.title);
147             pContent->SetAdditionalText(notificationItem.additionalText);
148             auto content = std::make_shared<NotificationContent>(pContent);
149             request->SetContent(content);
150             break;
151         }
152         case NotificationContent::Type::LONG_TEXT: {
153             ConvertBoxToLongContent(notificationItem, box, request);
154             break;
155         }
156         case NotificationContent::Type::MULTILINE: {
157             ConvertBoxToMultileContent(notificationItem, box, request);
158             break;
159         }
160         case NotificationContent::Type::PICTURE: {
161             ConvertBoxToPictureContent(notificationItem, box, request);
162             break;
163         }
164         default: {
165             ANS_LOGE("Set notifictaion content %{public}d", type);
166             break;
167         }
168     }
169 }
170 
MakeNotifictaionContent(const NotifticationRequestBox & box,sptr<NotificationRequest> & request,bool isCommonLiveView,int32_t contentType)171 void DistributedService::MakeNotifictaionContent(const NotifticationRequestBox& box, sptr<NotificationRequest>& request,
172     bool isCommonLiveView, int32_t contentType)
173 {
174     if (isCommonLiveView) {
175         std::vector<uint8_t> buffer;
176         if (box.GetCommonLiveView(buffer)) {
177             int64_t deleteTime;
178             std::string context;
179             auto liveviewContent = std::make_shared<NotificationLiveViewContent>();
180             if (box.GetNotificationText(context)) {
181                 liveviewContent->SetText(context);
182             }
183             if (box.GetNotificationTitle(context)) {
184                 liveviewContent->SetTitle(context);
185             }
186             if (box.GetAutoDeleteTime(deleteTime)) {
187                 request->SetAutoDeletedTime(deleteTime);
188             }
189             if (box.GetFinishTime(deleteTime)) {
190                 request->SetFinishDeadLine(deleteTime);
191             }
192             auto content = std::make_shared<NotificationContent>(liveviewContent);
193             request->SetContent(content);
194             std::shared_ptr<AAFwk::WantParams> extraInfo = std::make_shared<AAFwk::WantParams>();
195             liveviewContent->SetExtraInfo(extraInfo);
196             DISTRIBUTED_LIVEVIEW_ALL_SCENARIOS_EXTENTION_WRAPPER->UpdateLiveviewDecodeContent(request, buffer);
197         }
198         return;
199     }
200     SetNotifictaionContent(box, request, contentType);
201 }
202 
MakeNotifictaionIcon(const NotifticationRequestBox & box,sptr<NotificationRequest> & request,bool isCommonLiveView)203 void DistributedService::MakeNotifictaionIcon(const NotifticationRequestBox& box, sptr<NotificationRequest>& request,
204     bool isCommonLiveView)
205 {
206     std::shared_ptr<Media::PixelMap> icon;
207     if (box.GetBigIcon(icon)) {
208         request->SetBigIcon(icon);
209     }
210     if (box.GetOverlayIcon(icon)) {
211         request->SetOverlayIcon(icon);
212     }
213 
214     if (isCommonLiveView) {
215         std::string bundleName;
216         if (!box.GetCreatorBundleName(bundleName)) {
217             return;
218         }
219         std::string icon;
220         DistributedPreferences::GetInstance().GetIconByBundleName(bundleName, icon);
221         if (!icon.empty()) {
222             auto iconPixelMap = AnsImageUtil::UnPackImage(icon);
223             request->SetLittleIcon(iconPixelMap);
224         }
225     }
226 }
227 
MakeNotifictaionReminderFlag(const NotifticationRequestBox & box,sptr<NotificationRequest> & request)228 void DistributedService::MakeNotifictaionReminderFlag(const NotifticationRequestBox& box,
229     sptr<NotificationRequest>& request)
230 {
231     int32_t type = 0;
232     std::string context;
233     if (box.GetSlotType(type)) {
234         request->SetSlotType(static_cast<NotificationConstant::SlotType>(type));
235     }
236     if (box.GetReminderFlag(type)) {
237         request->SetCollaboratedReminderFlag(static_cast<uint32_t>(type));
238     }
239     if (box.GetCreatorBundleName(context)) {
240         request->SetOwnerBundleName(context);
241         request->SetCreatorBundleName(context);
242     }
243     if (box.GetNotificationHashCode(context)) {
244         request->SetDistributedHashCode(context);
245     }
246     request->SetDistributedCollaborate(true);
247     request->SetLabel(DISTRIBUTED_LABEL);
248 }
249 
MakeNotificationButtons(const NotifticationRequestBox & box,NotificationConstant::SlotType slotType,sptr<NotificationRequest> & request)250 void DistributedService::MakeNotificationButtons(const NotifticationRequestBox& box,
251     NotificationConstant::SlotType slotType, sptr<NotificationRequest>& request)
252 {
253     if (request != nullptr && slotType == NotificationConstant::SlotType::SOCIAL_COMMUNICATION) {
254         std::string actionName;
255         std::string userInputKey;
256         box.GetNotificationActionName(actionName);
257         box.GetNotificationUserInput(userInputKey);
258         std::shared_ptr<NotificationUserInput> userInput  = NotificationUserInput::Create(userInputKey);
259         std::shared_ptr<NotificationActionButton> actionButton =
260             NotificationActionButton::Create(nullptr, actionName, nullptr);
261         actionButton->AddNotificationUserInput(userInput);
262         request->AddActionButton(actionButton);
263     }
264 }
265 
PublishNotifictaion(const std::shared_ptr<TlvBox> & boxMessage)266 void DistributedService::PublishNotifictaion(const std::shared_ptr<TlvBox>& boxMessage)
267 {
268     sptr<NotificationRequest> request = new (std::nothrow) NotificationRequest();
269     if (request == nullptr) {
270         ANS_LOGE("NotificationRequest is nullptr");
271         return;
272     }
273     int32_t slotType = 0;
274     int32_t contentType = 0;
275     NotifticationRequestBox requestBox = NotifticationRequestBox(boxMessage);
276     bool isCommonLiveView = false;
277     if (requestBox.GetSlotType(slotType) && requestBox.GetContentType(contentType)) {
278         isCommonLiveView =
279             (static_cast<NotificationContent::Type>(contentType) == NotificationContent::Type::LIVE_VIEW) &&
280             (static_cast<NotificationConstant::SlotType>(slotType) == NotificationConstant::SlotType::LIVE_VIEW);
281     }
282     MakeNotificationButtons(requestBox, static_cast<NotificationConstant::SlotType>(slotType), request);
283     MakeNotifictaionContent(requestBox, request, isCommonLiveView, contentType);
284     MakeNotifictaionIcon(requestBox, request, isCommonLiveView);
285     MakeNotifictaionReminderFlag(requestBox, request);
286     int result = IN_PROCESS_CALL(NotificationHelper::PublishNotification(*request));
287     ANS_LOGI("Dans publish message %{public}s %{public}d.", request->Dump().c_str(), result);
288 }
289 
RemoveNotification(const std::shared_ptr<TlvBox> & boxMessage)290 void DistributedService::RemoveNotification(const std::shared_ptr<TlvBox>& boxMessage)
291 {
292     std::string hashCode;
293     int32_t slotType;
294     if (boxMessage == nullptr) {
295         ANS_LOGE("boxMessage is nullptr");
296         return;
297     }
298     boxMessage->GetStringValue(NOTIFICATION_HASHCODE, hashCode);
299     boxMessage->GetInt32Value(NOTIFICATION_SLOT_TYPE, slotType);
300 
301     int result = IN_PROCESS_CALL(NotificationHelper::RemoveNotification(
302         hashCode, NotificationConstant::DISTRIBUTED_COLLABORATIVE_DELETE));
303     std::string errorReason = "delete message failed";
304     code_ = DELETE_ERROR_EVENT_CODE;
305     if (result == 0) {
306         errorReason = "delete message success";
307         AbnormalReporting(result, BRANCH4_ID, errorReason);
308         OperationalReporting(OPERATION_DELETE_BRANCH, slotType);
309     } else {
310         AbnormalReporting(result, BRANCH3_ID, errorReason);
311     }
312     ANS_LOGI("dans remove message %{public}d.", result);
313 }
314 
RemoveNotifications(const std::shared_ptr<TlvBox> & boxMessage)315 void DistributedService::RemoveNotifications(const std::shared_ptr<TlvBox>& boxMessage)
316 {
317     std::vector<std::string> hashCodes;
318     std::string hashCodesString;
319     if (boxMessage == nullptr) {
320         ANS_LOGE("boxMessage is nullptr");
321         return;
322     }
323     if (!boxMessage->GetStringValue(NOTIFICATION_HASHCODE, hashCodesString)) {
324         ANS_LOGE("failed GetStringValue from boxMessage");
325         return;
326     }
327     std::istringstream hashCodesStream(hashCodesString);
328     std::string hashCode;
329     while (hashCodesStream >> hashCode) {
330         if (!hashCode.empty()) {
331             hashCodes.push_back(hashCode);
332         }
333     }
334 
335     int result = IN_PROCESS_CALL(
336         NotificationHelper::RemoveNotifications(hashCodes, NotificationConstant::DISTRIBUTED_COLLABORATIVE_DELETE));
337     ANS_LOGI("dans batch remove message %{public}d.", result);
338     std::string errorReason = "delete message failed";
339     code_ = DELETE_ERROR_EVENT_CODE;
340     if (result == 0) {
341         errorReason = "delete message success";
342         AbnormalReporting(result, BRANCH4_ID, errorReason);
343         std::string slotTypesString;
344         if (!boxMessage->GetStringValue(BATCH_REMOVE_SLOT_TYPE, slotTypesString)) {
345             ANS_LOGE("failed GetStringValue from boxMessage");
346             return;
347         }
348         std::istringstream slotTypesStream(slotTypesString);
349         std::string slotTypeString;
350         while (slotTypesStream >> slotTypeString) {
351             if (!slotTypeString.empty()) {
352                 OperationalReporting(OPERATION_DELETE_BRANCH, std::stoi(slotTypeString));
353             }
354         }
355     } else {
356         AbnormalReporting(result, BRANCH3_ID, errorReason);
357     }
358 }
359 
AbnormalReporting(int result,uint32_t branchId,const std::string & errorReason)360 void DistributedService::AbnormalReporting(int result, uint32_t branchId, const std::string &errorReason)
361 {
362     if (localDevice_.deviceType_ != DistributedHardware::DmDeviceType::DEVICE_TYPE_PHONE) {
363         return;
364     }
365     if (result != 0) {
366         SendEventReport(0, result, errorReason);
367     }
368     if (haCallback_ == nullptr) {
369         return;
370     }
371     haCallback_(code_, result, branchId, errorReason);
372 }
373 
OperationalReporting(int branchId,int32_t slotType)374 void DistributedService::OperationalReporting(int branchId, int32_t slotType)
375 {
376     if (haCallback_ == nullptr ||
377         localDevice_.deviceType_ != DistributedHardware::DmDeviceType::DEVICE_TYPE_PHONE) {
378         return;
379     }
380     std::string reason;
381     haCallback_(ANS_CUSTOMIZE_CODE, slotType, branchId, reason);
382 }
383 
HandleNotificationSync(const std::shared_ptr<TlvBox> & boxMessage)384 void DistributedService::HandleNotificationSync(const std::shared_ptr<TlvBox>& boxMessage)
385 {
386     bool empty = true;
387     NotificationSyncBox notificationSyncBox = NotificationSyncBox(boxMessage);
388     if (!notificationSyncBox.GetNotificationEmpty(empty)) {
389         ANS_LOGW("Dans get sync notification empty failed.");
390         return;
391     }
392 
393     std::unordered_set<std::string> notificationList;
394     if (!empty) {
395         if (!notificationSyncBox.GetNotificationList(notificationList)) {
396             ANS_LOGW("Dans get sync notification failed.");
397             return;
398         }
399     }
400     std::vector<sptr<Notification>> notifications;
401     auto result = NotificationHelper::GetAllNotificationsBySlotType(notifications,
402         NotificationConstant::SlotType::LIVE_VIEW);
403     if (result != ERR_OK || notifications.empty()) {
404         ANS_LOGI("Dans get all active %{public}d %{public}d.", result, notifications.empty());
405         return;
406     }
407 
408     ANS_LOGI("Dans handle sync notification %{public}d %{public}d.", (int32_t)(notificationList.size()),
409         (int32_t)(notifications.size()));
410     for (auto item : notificationList) {
411         ANS_LOGI("Dans sync %{public}s.", item.c_str());
412     }
413     std::vector<std::string> removeList;
414     for (auto& notification : notifications) {
415         if (notification == nullptr || notification->GetNotificationRequestPoint() == nullptr ||
416             !notification->GetNotificationRequestPoint()->IsCommonLiveView()) {
417             ANS_LOGI("Dans no need sync remove notification.");
418             continue;
419         }
420         std::string hashCode = notification->GetKey();
421         ANS_LOGI("Dans sync remove %{public}s.", hashCode.c_str());
422         size_t pos = hashCode.find(DISTRIBUTED_LABEL);
423         if (pos != std::string::npos) {
424             hashCode.erase(pos, DISTRIBUTED_LABEL.length());
425         }
426         if (notificationList.find(hashCode) == notificationList.end()) {
427             removeList.push_back(notification->GetKey());
428             ANS_LOGI("Dans sync remove notification %{public}s.", notification->GetKey().c_str());
429         }
430     }
431     if (!removeList.empty()) {
432         int result = IN_PROCESS_CALL(NotificationHelper::RemoveNotifications(removeList,
433             NotificationConstant::DISTRIBUTED_COLLABORATIVE_DELETE));
434         ANS_LOGI("Dans sync remove message %{public}d.", result);
435     }
436 }
437 
GetNotificationWantPtr(const std::string & hashCode)438 std::shared_ptr<AAFwk::Want> GetNotificationWantPtr(const std::string& hashCode)
439 {
440     sptr<NotificationRequest> notificationRequest = new (std::nothrow) NotificationRequest();
441     auto result = NotificationHelper::GetNotificationRequestByHashCode(hashCode, notificationRequest);
442     if (result != ERR_OK || notificationRequest == nullptr) {
443         ANS_LOGE("Check notificationRequest is null.");
444         return nullptr;
445     }
446 
447     std::shared_ptr<AbilityRuntime::WantAgent::WantAgent> wantAgentPtr = notificationRequest->GetWantAgent();
448     if (wantAgentPtr == nullptr) {
449         ANS_LOGE("Check wantAgentPtr is null.");
450         return nullptr;
451     }
452 
453     std::shared_ptr<AbilityRuntime::WantAgent::PendingWant> pendingWantPtr = wantAgentPtr->GetPendingWant();
454     if (pendingWantPtr == nullptr) {
455         ANS_LOGE("Check pendingWantPtr is null.");
456         return nullptr;
457     }
458 
459     return pendingWantPtr->GetWant(pendingWantPtr->GetTarget());
460 }
461 
TriggerJumpApplication(const std::string & hashCode)462 void DistributedService::TriggerJumpApplication(const std::string& hashCode)
463 {
464     auto wantPtr = GetNotificationWantPtr(hashCode);
465     if (wantPtr == nullptr) {
466         ANS_LOGE("Get pendingWantPtr is null.");
467         return;
468     }
469 
470     if (!PowerMgr::PowerMgrClient::GetInstance().IsScreenOn()) {
471         auto ret = PowerMgr::PowerMgrClient::GetInstance().WakeupDevice();
472         if (ret != PowerMgr::PowerErrors::ERR_OK) {
473             ANS_LOGW("Wake up device %{public}d", ret);
474             return;
475         }
476     }
477 
478     code_ = MODIFY_ERROR_EVENT_CODE;
479     if (ScreenLock::ScreenLockManager::GetInstance()->IsScreenLocked()) {
480         OperationInfo info;
481         info.type = OperationType::DISTRIBUTE_OPERATION_JUMP;
482         info.eventId = std::to_string(GetCurrentTime());
483         sptr<UnlockScreenCallback> listener = new (std::nothrow) UnlockScreenCallback(info.eventId);
484         int32_t unlockResult =
485             ScreenLock::ScreenLockManager::GetInstance()->Unlock(ScreenLock::Action::UNLOCKSCREEN, listener);
486         ANS_LOGI("unlock result:%{public}d", unlockResult);
487         if (unlockResult != ERR_OK) {
488             std::string errorReason = "unlock failed";
489             AbnormalReporting(unlockResult, BRANCH6_ID, errorReason);
490         }
491         info.want = *wantPtr;
492         OperationService::GetInstance().AddOperation(info);
493     } else {
494         auto ret = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(*wantPtr);
495         ANS_LOGI("StartAbility result:%{public}d", ret);
496         std::string errorReason = "pull up success";
497         if (ret == ERR_OK) {
498             OperationalReporting(BRANCH3_ID, NotificationConstant::SlotType::LIVE_VIEW);
499         } else {
500             errorReason = "pull up failed";
501             int32_t messageType = 0;
502             AbnormalReporting(messageType, ret, errorReason);
503         }
504         AbnormalReporting(ret, BRANCH9_ID, errorReason);
505     }
506 }
507 
GetNotificationButtonWantPtr(const std::string & hashCode,const std::string & actionName,std::shared_ptr<AAFwk::Want> & wantPtr,sptr<NotificationRequest> & request,std::string & userInputKey)508 ErrCode DistributedService::GetNotificationButtonWantPtr(const std::string& hashCode,
509     const std::string& actionName, std::shared_ptr<AAFwk::Want>& wantPtr, sptr<NotificationRequest>& request,
510     std::string& userInputKey)
511 {
512     sptr<NotificationRequest> notificationRequest = nullptr;
513     auto result = NotificationHelper::GetNotificationRequestByHashCode(hashCode, notificationRequest);
514     if (result != ERR_OK || notificationRequest == nullptr) {
515         ANS_LOGE("Check notificationRequest is null.");
516         return ERR_ANS_NOTIFICATION_NOT_EXISTS;
517     }
518 
519     request = notificationRequest;
520     auto actionButtons = notificationRequest->GetActionButtons();
521     if (actionButtons.empty()) {
522         ANS_LOGE("Check actionButtons is null.");
523         return ERR_ANS_INVALID_PARAM;
524     }
525 
526     std::shared_ptr<NotificationActionButton> button = nullptr;
527     for (std::shared_ptr<NotificationActionButton> buttonItem : actionButtons) {
528         if (buttonItem != nullptr && buttonItem->GetUserInput() != nullptr &&
529             buttonItem->GetTitle() == actionName) {
530             button = buttonItem;
531             break;
532         }
533     }
534 
535     if (button == nullptr) {
536         ANS_LOGE("Check user input is null %{public}s.", actionName.c_str());
537         return ERR_ANS_INVALID_PARAM;
538     }
539     if (button->GetUserInput() != nullptr) {
540         userInputKey = button->GetUserInput()->GetInputKey();
541     }
542     if (userInputKey.empty()) {
543         ANS_LOGE("Check userInputKey is null.");
544         return ERR_ANS_INVALID_PARAM;
545     }
546     std::shared_ptr<AbilityRuntime::WantAgent::WantAgent> wantAgentPtr = button->GetWantAgent();
547     if (wantAgentPtr == nullptr) {
548         ANS_LOGE("Check wantAgentPtr is null.");
549         return ERR_ANS_INVALID_PARAM;
550     }
551 
552     std::shared_ptr<AbilityRuntime::WantAgent::PendingWant> pendingWantPtr = wantAgentPtr->GetPendingWant();
553     if (pendingWantPtr == nullptr) {
554         ANS_LOGE("Check pendingWantPtr is null.");
555         return ERR_ANS_INVALID_PARAM;
556     }
557 
558     wantPtr = pendingWantPtr->GetWant(pendingWantPtr->GetTarget());
559     if (wantPtr == nullptr) {
560         ANS_LOGE("Check wantPtr is null.");
561         return ERR_ANS_INVALID_PARAM;
562     }
563     return ERR_OK;
564 }
565 
TriggerReplyWantAgent(const sptr<NotificationRequest> request,std::string actionName,int32_t errorCode,std::string desc)566 void DistributedService::TriggerReplyWantAgent(const sptr<NotificationRequest> request,
567     std::string actionName, int32_t errorCode, std::string desc)
568 {
569     AAFwk::WantParams extraInfo;
570     extraInfo.SetParam("desc", AAFwk::String::Box(desc));
571     extraInfo.SetParam("errorCode", AAFwk::Integer::Box(errorCode));
572     extraInfo.SetParam("actionName", AAFwk::String::Box(actionName));
573     DISTRIBUTED_LIVEVIEW_ALL_SCENARIOS_EXTENTION_WRAPPER->TriggerPushWantAgent(request,
574         OperationType::DISTRIBUTE_OPERATION_REPLY, extraInfo);
575 }
576 
TriggerReplyApplication(const std::string & hashCode,const NotificationResponseBox & responseBox)577 ErrCode DistributedService::TriggerReplyApplication(const std::string& hashCode,
578     const NotificationResponseBox& responseBox)
579 {
580     std::string actionName;
581     std::string userInput;
582     std::string userInputKey;
583     responseBox.GetActionName(actionName);
584     responseBox.GetUserInput(userInput);
585 
586     code_ = MODIFY_ERROR_EVENT_CODE;
587     std::shared_ptr<AAFwk::Want> wantPtr = nullptr;
588     sptr<NotificationRequest> request = nullptr;
589     auto result = GetNotificationButtonWantPtr(hashCode, actionName, wantPtr, request, userInputKey);
590     if (result != ERR_OK || wantPtr == nullptr) {
591         AbnormalReporting(result, BRANCH4_ID, "reply get button failed");
592         TriggerReplyWantAgent(request, actionName, result, "reply get button failed");
593         return result;
594     }
595 
596     if (wantPtr->GetBoolParam(AAFwk::Want::PARAM_RESV_CALL_TO_FOREGROUND, false)) {
597         ANS_LOGE("Not support foreground.");
598         AbnormalReporting(ERR_ANS_DISTRIBUTED_OPERATION_FAILED, BRANCH4_ID, "reply foreground failed");
599         TriggerReplyWantAgent(request, actionName, ERR_ANS_DISTRIBUTED_OPERATION_FAILED, "reply foreground failed");
600         return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
601     }
602 
603     auto ret = AbilityManagerHelper::GetInstance().ConnectAbility(hashCode, *wantPtr,
604         userInputKey, userInput);
605     ANS_LOGI("StartAbility result:%{public}d", ret);
606     if (ret == ERR_OK) {
607         TriggerReplyWantAgent(request, actionName, ERR_OK, "");
608         OperationalReporting(BRANCH4_ID, NotificationConstant::SlotType::SOCIAL_COMMUNICATION);
609     } else {
610         TriggerReplyWantAgent(request, actionName, ret, "ability reply failed");
611         AbnormalReporting(ret, BRANCH4_ID, "ability reply failed");
612         return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
613     }
614     return ERR_OK;
615 }
616 
HandleOperationResponse(const std::string & hashCode,const NotificationResponseBox & responseBox)617 void DistributedService::HandleOperationResponse(const std::string& hashCode,
618     const NotificationResponseBox& responseBox)
619 {
620     int32_t result = 0;
621     std::string eventId;
622     responseBox.GetOperationEventId(eventId);
623     responseBox.GetResponseResult(result);
624     auto ret = NotificationHelper::ReplyDistributeOperation(DISTRIBUTED_LABEL + hashCode + eventId, result);
625     ANS_LOGI("HandleOperationResponse hashcode %{public}s, result:%{public}d %{public}d",
626         hashCode.c_str(), result, ret);
627 }
628 
ReplyOperationResponse(const std::string & hashCode,const NotificationResponseBox & responseBox,OperationType operationType,uint32_t result)629 void DistributedService::ReplyOperationResponse(const std::string& hashCode,
630     const NotificationResponseBox& responseBox, OperationType operationType, uint32_t result)
631 {
632     std::string eventId;
633     std::string deviceId;
634     responseBox.GetOperationEventId(eventId);
635     responseBox.GetLocalDeviceId(deviceId);
636 
637     auto iter = peerDevice_.find(deviceId);
638     if (iter == peerDevice_.end()) {
639         ANS_LOGI("Dans get deviceId unknonw %{public}s.", StringAnonymous(deviceId).c_str());
640         return;
641     }
642 
643     NotificationResponseBox replyBox;
644     replyBox.SetResponseResult(result);
645     replyBox.SetNotificationHashCode(hashCode);
646     replyBox.SetOperationEventId(eventId);
647     replyBox.SetMatchType(MatchType::MATCH_ACK);
648     replyBox.SetOperationType(operationType);
649 
650     if (!replyBox.Serialize()) {
651         ANS_LOGW("dans OnResponse reply serialize failed");
652         return;
653     }
654     auto ret = DistributedClient::GetInstance().SendMessage(replyBox.GetByteBuffer(), replyBox.GetByteLength(),
655         TransDataType::DATA_TYPE_MESSAGE, iter->second.deviceId_, iter->second.deviceType_);
656     if (ret != ERR_OK) {
657         ANS_LOGE("dans OnResponse send message failed result: %{public}d", ret);
658         return;
659     }
660     ANS_LOGI("Dans reply operation %{public}s %{public}d.", StringAnonymous(iter->second.deviceId_).c_str(), result);
661     return;
662 }
663 
HandleResponseSync(const std::shared_ptr<TlvBox> & boxMessage)664 void DistributedService::HandleResponseSync(const std::shared_ptr<TlvBox>& boxMessage)
665 {
666     int32_t operationType = 0;
667     int32_t matchType = 0;
668     std::string hashCode;
669     NotificationResponseBox responseBox = NotificationResponseBox(boxMessage);
670     responseBox.GetOperationType(operationType);
671     responseBox.GetMatchType(matchType);
672     responseBox.GetNotificationHashCode(hashCode);
673     ANS_LOGI("handle response, hashCode: %{public}s type: %{public}d %{public}d.",
674         hashCode.c_str(), operationType, matchType);
675 
676     if (matchType == MatchType::MATCH_SYN) {
677         if (static_cast<OperationType>(operationType) == OperationType::DISTRIBUTE_OPERATION_JUMP) {
678             TriggerJumpApplication(hashCode);
679         } else if (static_cast<OperationType>(operationType) == OperationType::DISTRIBUTE_OPERATION_REPLY) {
680             ErrCode result = TriggerReplyApplication(hashCode, responseBox);
681             ReplyOperationResponse(hashCode, responseBox, OperationType::DISTRIBUTE_OPERATION_REPLY, result);
682         }
683     } else if (matchType == MatchType::MATCH_ACK) {
684         HandleOperationResponse(hashCode, responseBox);
685     }
686 }
687 }
688 }
689