1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "notification_tools.h"
17
18 #include <sstream>
19 #ifdef DISTRIBUTED_NOTIFICATION_ENABLE
20 #include "notification_helper.h"
21 #endif
22 #include "continuous_task_log.h"
23 #include "string_wrapper.h"
24
25 #ifdef BGTASK_MGR_UNIT_TEST
26 #define WEAK_FUNC __attribute__((weak))
27 #else
28 #define WEAK_FUNC
29 #endif
30
31 namespace OHOS {
32 namespace BackgroundTaskMgr {
33 namespace {
34 constexpr char NOTIFICATION_PREFIX[] = "bgmode";
35 constexpr char SEPARATOR[] = "_";
36 #ifdef DISTRIBUTED_NOTIFICATION_ENABLE
37 constexpr int BACKGROUND_MODE_DATA_TANSFER = 1;
38 constexpr int BACKGROUND_MODE_AUDIO_RECORDING = 3;
39 constexpr int BACKGROUND_MODE_VOIP = 8;
40 constexpr int PUBLISH_DELAY_TIME = 3;
41 constexpr int TYPE_CODE_VOIP = 0;
42 constexpr int TYPE_CODE_AUDIO_RECORDING = 7;
43 constexpr int TYPE_CODE_DATA_TANSFER = 8;
44 #endif
45 }
46
47 int32_t NotificationTools::notificationIdIndex_ = -1;
NotificationTools()48 NotificationTools::NotificationTools() {}
49
~NotificationTools()50 NotificationTools::~NotificationTools() {}
51
SetNotificationIdIndex(const int32_t id)52 void NotificationTools::SetNotificationIdIndex(const int32_t id)
53 {
54 notificationIdIndex_ = id;
55 }
56
CreateNotificationLabel(int32_t uid,const std::string & bundleName,const std::string & abilityName,int32_t abilityId)57 std::string CreateNotificationLabel(int32_t uid, const std::string &bundleName,
58 const std::string &abilityName, int32_t abilityId)
59 {
60 std::stringstream stream;
61 stream.clear();
62 stream.str("");
63 stream << NOTIFICATION_PREFIX << SEPARATOR << uid << SEPARATOR << std::hash<std::string>()(abilityName) <<
64 SEPARATOR << abilityId;
65 std::string label = stream.str();
66 BGTASK_LOGD("notification label: %{public}s", label.c_str());
67 return label;
68 }
69
PublishNotification(const std::shared_ptr<ContinuousTaskRecord> & continuousTaskRecord,const std::string & appName,const std::string & prompt,int32_t serviceUid)70 WEAK_FUNC ErrCode NotificationTools::PublishNotification(
71 const std::shared_ptr<ContinuousTaskRecord> &continuousTaskRecord,
72 const std::string &appName, const std::string &prompt, int32_t serviceUid)
73 {
74 #ifdef DISTRIBUTED_NOTIFICATION_ENABLE
75 std::shared_ptr<Notification::NotificationLocalLiveViewContent> liveContent
76 = std::make_shared<Notification::NotificationLocalLiveViewContent>();
77 liveContent->SetTitle(appName);
78 liveContent->SetText(prompt);
79 if (std::find(continuousTaskRecord->bgModeIds_.begin(), continuousTaskRecord->bgModeIds_.end(),
80 BACKGROUND_MODE_DATA_TANSFER) != continuousTaskRecord->bgModeIds_.end()) {
81 liveContent->SetType(TYPE_CODE_DATA_TANSFER);
82 } else if (std::find(continuousTaskRecord->bgModeIds_.begin(), continuousTaskRecord->bgModeIds_.end(),
83 BACKGROUND_MODE_AUDIO_RECORDING) != continuousTaskRecord->bgModeIds_.end()) {
84 liveContent->SetType(TYPE_CODE_AUDIO_RECORDING);
85 } else if (std::find(continuousTaskRecord->bgModeIds_.begin(), continuousTaskRecord->bgModeIds_.end(),
86 BACKGROUND_MODE_VOIP) != continuousTaskRecord->bgModeIds_.end()) {
87 liveContent->SetType(TYPE_CODE_VOIP);
88 }
89
90 std::shared_ptr<AAFwk::WantParams> extraInfo = std::make_shared<AAFwk::WantParams>();
91 extraInfo->SetParam("abilityName", AAFwk::String::Box(continuousTaskRecord->abilityName_));
92
93 std::string notificationLabel = CreateNotificationLabel(continuousTaskRecord->uid_,
94 continuousTaskRecord->bundleName_, continuousTaskRecord->abilityName_,
95 continuousTaskRecord->abilityId_);
96
97 Notification::NotificationRequest notificationRequest = Notification::NotificationRequest();
98 notificationRequest.SetContent(std::make_shared<Notification::NotificationContent>(liveContent));
99 notificationRequest.SetAdditionalData(extraInfo);
100 notificationRequest.SetWantAgent(continuousTaskRecord->wantAgent_);
101 notificationRequest.SetCreatorUid(serviceUid);
102 notificationRequest.SetOwnerUid(continuousTaskRecord->GetUid());
103 notificationRequest.SetInProgress(true);
104 notificationRequest.SetIsAgentNotification(true);
105 notificationRequest.SetPublishDelayTime(PUBLISH_DELAY_TIME);
106 notificationRequest.SetUpdateByOwnerAllowed(true);
107 notificationRequest.SetSlotType(Notification::NotificationConstant::SlotType::LIVE_VIEW);
108 notificationRequest.SetLabel(notificationLabel);
109 if (continuousTaskRecord->GetNotificationId() == -1) {
110 notificationRequest.SetNotificationId(++notificationIdIndex_);
111 } else {
112 notificationRequest.SetNotificationId(continuousTaskRecord->GetNotificationId());
113 }
114 if (Notification::NotificationHelper::PublishNotification(notificationRequest) != ERR_OK) {
115 BGTASK_LOGE("publish notification error, %{public}s, %{public}d", notificationLabel.c_str(),
116 continuousTaskRecord->notificationId_);
117 return ERR_BGTASK_NOTIFICATION_ERR;
118 }
119 continuousTaskRecord->notificationLabel_ = notificationLabel;
120 if (continuousTaskRecord->GetNotificationId() == -1) {
121 continuousTaskRecord->notificationId_ = notificationIdIndex_;
122 }
123 #endif
124 return ERR_OK;
125 }
126
CancelNotification(const std::string & label,int32_t id)127 WEAK_FUNC ErrCode NotificationTools::CancelNotification(const std::string &label, int32_t id)
128 {
129 #ifdef DISTRIBUTED_NOTIFICATION_ENABLE
130 if (Notification::NotificationHelper::CancelNotification(label, id) != ERR_OK) {
131 BGTASK_LOGE("CancelNotification error label %{public}s, id %{public}d", label.c_str(), id);
132 return ERR_BGTASK_NOTIFICATION_ERR;
133 }
134 #endif
135 return ERR_OK;
136 }
137
GetAllActiveNotificationsLabels(std::set<std::string> & notificationLabels)138 WEAK_FUNC void NotificationTools::GetAllActiveNotificationsLabels(std::set<std::string> ¬ificationLabels)
139 {
140 #ifdef DISTRIBUTED_NOTIFICATION_ENABLE
141 std::vector<sptr<Notification::Notification>> notifications;
142 ErrCode ret = Notification::NotificationHelper::GetAllActiveNotifications(notifications);
143 if (ret != ERR_OK) {
144 BGTASK_LOGE("get all active notification fail!");
145 return;
146 }
147 for (auto &var : notifications) {
148 notificationLabels.emplace(var->GetLabel());
149 }
150 #endif
151 }
152
RefreshContinuousNotifications(const std::map<std::string,std::pair<std::string,std::string>> & newPromptInfos,int32_t serviceUid)153 WEAK_FUNC void NotificationTools::RefreshContinuousNotifications(
154 const std::map<std::string, std::pair<std::string, std::string>> &newPromptInfos, int32_t serviceUid)
155 {
156 #ifdef DISTRIBUTED_NOTIFICATION_ENABLE
157 std::vector<sptr<Notification::Notification>> notifications;
158 ErrCode ret = Notification::NotificationHelper::GetAllActiveNotifications(notifications);
159 if (ret != ERR_OK) {
160 BGTASK_LOGE("get all active notification fail!");
161 return;
162 }
163 for (auto &var : notifications) {
164 Notification::NotificationRequest request = var->GetNotificationRequest();
165 std::string label = var->GetLabel();
166 if (newPromptInfos.count(label) == 0 || request.GetCreatorUid() != serviceUid) {
167 continue;
168 }
169 auto &content = request.GetContent();
170 auto const &normalContent = content->GetNotificationContent();
171 normalContent->SetTitle(newPromptInfos.at(label).first);
172 normalContent->SetText(newPromptInfos.at(label).second);
173 if (Notification::NotificationHelper::PublishContinuousTaskNotification(request) != ERR_OK) {
174 BGTASK_LOGE("refresh notification error");
175 }
176 }
177 #endif
178 }
179 }
180 }
181