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