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 "distributed_subscriber.h"
17
18 #include "ans_log_wrapper.h"
19 #include "distributed_service.h"
20 #include "notification_config_parse.h"
21 #include "distributed_preferences.h"
22 #include "distributed_local_config.h"
23 #include "distributed_device_service.h"
24
25 namespace OHOS {
26 namespace Notification {
27
~DistribuedSubscriber()28 DistribuedSubscriber::~DistribuedSubscriber()
29 {
30 }
31
OnDied()32 void DistribuedSubscriber::OnDied()
33 {
34 ANS_LOGW("Subscriber on died %{public}d %{public}s %{public}d %{public}s.",
35 peerDevice_.deviceType_, StringAnonymous(peerDevice_.deviceId_).c_str(), localDevice_.deviceType_,
36 StringAnonymous(localDevice_.deviceId_).c_str());
37 }
38
OnConnected()39 void DistribuedSubscriber::OnConnected()
40 {
41 ANS_LOGI("Subscriber on connected %{public}d %{public}s %{public}d %{public}s.",
42 peerDevice_.deviceType_, StringAnonymous(peerDevice_.deviceId_).c_str(), localDevice_.deviceType_,
43 StringAnonymous(localDevice_.deviceId_).c_str());
44 }
45
OnDisconnected()46 void DistribuedSubscriber::OnDisconnected()
47 {
48 ANS_LOGI("Subscriber on disconnected %{public}d %{public}s %{public}d %{public}s.",
49 peerDevice_.deviceType_, StringAnonymous(peerDevice_.deviceId_).c_str(), localDevice_.deviceType_,
50 StringAnonymous(localDevice_.deviceId_).c_str());
51 }
52
OnCanceled(const std::shared_ptr<Notification> & request,const std::shared_ptr<NotificationSortingMap> & sortingMap,int32_t deleteReason)53 void DistribuedSubscriber::OnCanceled(const std::shared_ptr<Notification> &request,
54 const std::shared_ptr<NotificationSortingMap> &sortingMap, int32_t deleteReason)
55 {
56 ANS_LOGI("Subscriber on canceled %{public}d %{public}s %{public}d %{public}s.",
57 peerDevice_.deviceType_, StringAnonymous(peerDevice_.deviceId_).c_str(), localDevice_.deviceType_,
58 StringAnonymous(localDevice_.deviceId_).c_str());
59 if (deleteReason == NotificationConstant::DISTRIBUTED_COLLABORATIVE_DELETE ||
60 deleteReason == NotificationConstant::DISTRIBUTED_ENABLE_CLOSE_DELETE ||
61 deleteReason == NotificationConstant::DISTRIBUTED_RELEASE_DELETE) {
62 ANS_LOGD("is cross device deletion");
63 return;
64 }
65
66 if (CheckNeedCollaboration(request)) {
67 DistributedService::GetInstance().OnCanceled(request, peerDevice_);
68 }
69 }
70
OnConsumed(const std::shared_ptr<Notification> & request,const std::shared_ptr<NotificationSortingMap> & sortingMap)71 void DistribuedSubscriber::OnConsumed(const std::shared_ptr<Notification> &request,
72 const std::shared_ptr<NotificationSortingMap> &sortingMap)
73 {
74 ANS_LOGI("Subscriber on consumed %{public}d %{public}s %{public}d %{public}s.",
75 peerDevice_.deviceType_, StringAnonymous(peerDevice_.deviceId_).c_str(), localDevice_.deviceType_,
76 StringAnonymous(localDevice_.deviceId_).c_str());
77 if (localDevice_.deviceType_ != DistributedHardware::DmDeviceType::DEVICE_TYPE_PHONE) {
78 ANS_LOGI("No need consumed notification %{public}d %{public}s.",
79 localDevice_.deviceType_, StringAnonymous(localDevice_.deviceId_).c_str());
80 return;
81 }
82 if (peerDevice_.deviceType_ == DistributedHardware::DmDeviceType::DEVICE_TYPE_WATCH) {
83 DistributedService::GetInstance().OnConsumed(request, peerDevice_);
84 return;
85 }
86 if (request == nullptr || request->GetNotificationRequestPoint() == nullptr) {
87 return;
88 }
89 auto requestPoint = request->GetNotificationRequestPoint();
90 auto params = requestPoint->GetExtendInfo();
91 if (params == nullptr) {
92 ANS_LOGI("Dans OnConsumed invalid extend info.");
93 return;
94 }
95 std::string deviceId = params->GetStringParam("notification_collaboration_deviceId_" +
96 DistributedDeviceService::DeviceTypeToTypeString(peerDevice_.deviceType_));
97 if (deviceId.empty() || deviceId != peerDevice_.udid_) {
98 ANS_LOGI("Dans OnConsumed invalid device %{public}s %{public}s.", StringAnonymous(deviceId).c_str(),
99 StringAnonymous(peerDevice_.deviceId_).c_str());
100 return;
101 }
102 DistributedService::GetInstance().OnConsumed(request, peerDevice_);
103 }
104
OnUpdate(const std::shared_ptr<NotificationSortingMap> & sortingMap)105 void DistribuedSubscriber::OnUpdate(const std::shared_ptr<NotificationSortingMap> &sortingMap)
106 {
107 ANS_LOGI("Subscriber on update.");
108 }
109
OnDoNotDisturbDateChange(const std::shared_ptr<NotificationDoNotDisturbDate> & date)110 void DistribuedSubscriber::OnDoNotDisturbDateChange(const std::shared_ptr<NotificationDoNotDisturbDate> &date)
111 {
112 }
113
OnEnabledNotificationChanged(const std::shared_ptr<EnabledNotificationCallbackData> & callbackData)114 void DistribuedSubscriber::OnEnabledNotificationChanged(
115 const std::shared_ptr<EnabledNotificationCallbackData> &callbackData)
116 {
117 }
118
OnBadgeChanged(const std::shared_ptr<BadgeNumberCallbackData> & badgeData)119 void DistribuedSubscriber::OnBadgeChanged(const std::shared_ptr<BadgeNumberCallbackData> &badgeData)
120 {
121 }
122
OnBadgeEnabledChanged(const sptr<EnabledNotificationCallbackData> & callbackData)123 void DistribuedSubscriber::OnBadgeEnabledChanged(const sptr<EnabledNotificationCallbackData> &callbackData)
124 {
125 }
126
OnBatchCanceled(const std::vector<std::shared_ptr<Notification>> & requestList,const std::shared_ptr<NotificationSortingMap> & sortingMap,int32_t deleteReason)127 void DistribuedSubscriber::OnBatchCanceled(const std::vector<std::shared_ptr<Notification>> &requestList,
128 const std::shared_ptr<NotificationSortingMap> &sortingMap, int32_t deleteReason)
129 {
130 ANS_LOGI("Subscriber on batch canceled %{public}d %{public}s %{public}d %{public}s.",
131 peerDevice_.deviceType_, StringAnonymous(peerDevice_.deviceId_).c_str(), localDevice_.deviceType_,
132 StringAnonymous(localDevice_.deviceId_).c_str());
133 if (deleteReason == NotificationConstant::DISTRIBUTED_COLLABORATIVE_DELETE ||
134 deleteReason == NotificationConstant::DISTRIBUTED_ENABLE_CLOSE_DELETE ||
135 deleteReason == NotificationConstant::DISTRIBUTED_RELEASE_DELETE) {
136 ANS_LOGD("is cross device deletion");
137 return;
138 }
139 std::vector<std::shared_ptr<Notification>> notifications;
140 for (auto notification : requestList) {
141 if (CheckNeedCollaboration(notification)) {
142 notifications.push_back(notification);
143 }
144 }
145 if (!notifications.empty()) {
146 DistributedService::GetInstance().OnBatchCanceled(notifications, peerDevice_);
147 }
148 }
149
OnOperationResponse(const std::shared_ptr<NotificationOperationInfo> & operationInfo)150 ErrCode DistribuedSubscriber::OnOperationResponse(const std::shared_ptr<NotificationOperationInfo> &operationInfo)
151 {
152 DistributedDeviceInfo operRespDevice;
153 DistributedDeviceService::GetInstance().GetDeviceInfoByUdid(operationInfo->GetNotificationUdid(), operRespDevice);
154 ANS_LOGI("Subscriber on response %{public}d %{public}s %{public}d %{public}s, OperRespDeviceId: %{public}s.",
155 peerDevice_.deviceType_, StringAnonymous(peerDevice_.deviceId_).c_str(), localDevice_.deviceType_,
156 StringAnonymous(localDevice_.deviceId_).c_str(), StringAnonymous(operRespDevice.deviceId_).c_str());
157 if (localDevice_.deviceType_ != DistributedHardware::DmDeviceType::DEVICE_TYPE_WATCH &&
158 operRespDevice.deviceId_.compare(peerDevice_.deviceId_) != 0) {
159 return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
160 }
161 return DistributedService::GetInstance().OnOperationResponse(operationInfo, peerDevice_);
162 }
163
OnApplicationInfoNeedChanged(const std::string & bundleName)164 void DistribuedSubscriber::OnApplicationInfoNeedChanged(const std::string& bundleName)
165 {
166 ANS_LOGI("Notify changed %{public}s %{public}d.", bundleName.c_str(), localDevice_.deviceType_);
167 if (localDevice_.deviceType_ != DistributedHardware::DmDeviceType::DEVICE_TYPE_PHONE) {
168 return;
169 }
170 DistributedService::GetInstance().OnApplicationInfnChanged(bundleName);
171 }
172
SetLocalDevice(DistributedDeviceInfo localDevice)173 void DistribuedSubscriber::SetLocalDevice(DistributedDeviceInfo localDevice)
174 {
175 localDevice_ = localDevice;
176 }
177
SetPeerDevice(DistributedDeviceInfo peerDevice)178 void DistribuedSubscriber::SetPeerDevice(DistributedDeviceInfo peerDevice)
179 {
180 peerDevice_ = peerDevice;
181 }
182
CheckNeedCollaboration(const std::shared_ptr<Notification> & notification)183 bool DistribuedSubscriber::CheckNeedCollaboration(const std::shared_ptr<Notification>& notification)
184 {
185 if (notification == nullptr || notification->GetNotificationRequestPoint() == nullptr) {
186 ANS_LOGE("notification or request is nullptr");
187 return false;
188 }
189 if (!CheckCollaborativeRemoveType(notification->GetNotificationRequestPoint()->GetSlotType())) {
190 ANS_LOGE("CheckCollaborativeRemoveType failed");
191 return false;
192 }
193 return true;
194 }
195
CheckCollaborativeRemoveType(const NotificationConstant::SlotType & slotType)196 bool DistribuedSubscriber::CheckCollaborativeRemoveType(const NotificationConstant::SlotType& slotType)
197 {
198 auto type = SlotEnumToSring(slotType);
199 if (type.empty()) {
200 ANS_LOGW("slotType is undefine");
201 return false;
202 }
203
204 auto localDeviceType = DistributedDeviceService::DeviceTypeToTypeString(localDevice_.deviceType_);
205 auto peerDeviceType = DistributedDeviceService::DeviceTypeToTypeString(peerDevice_.deviceType_);
206 if (localDeviceType.empty() || peerDeviceType.empty()) {
207 ANS_LOGW("localDeviceType OR localDeviceType null");
208 return false;
209 }
210
211 if (!CheckTypeByCcmRule(type, localDeviceType, peerDeviceType)) {
212 return false;
213 }
214
215 return true;
216 }
217
CheckTypeByCcmRule(const std::string & slotType,const std::string & localDeviceType,const std::string & peerDeviceType)218 bool DistribuedSubscriber::CheckTypeByCcmRule(const std::string& slotType,
219 const std::string& localDeviceType, const std::string& peerDeviceType)
220 {
221 std::map<std::string, std::map<std::string, std::unordered_set<std::string>>> deleteConfigDevice;
222 DistributedLocalConfig::GetInstance().GetCollaborativeDeleteTypesByDevices(deleteConfigDevice);
223 if (deleteConfigDevice.empty()) {
224 ANS_LOGW("distributed delete ccm is undefined");
225 return false;
226 }
227
228 auto peerdeleteConfigDeviceIt = deleteConfigDevice.find(localDeviceType);
229 if (peerdeleteConfigDeviceIt == deleteConfigDevice.end()) {
230 ANS_LOGW("peerdeleteConfigDevice err, local:%{public}s, per:%{public}s",
231 localDeviceType.c_str(), peerDeviceType.c_str());
232 return false;
233 }
234
235 auto peerdeleteConfigDevice = peerdeleteConfigDeviceIt->second;
236 auto deleteSlotTypeListIt = peerdeleteConfigDevice.find(peerDeviceType);
237 if (deleteSlotTypeListIt == peerdeleteConfigDevice.end()) {
238 ANS_LOGW("deleteSlotTypeList err, local:%{public}s, per:%{public}s",
239 localDeviceType.c_str(), peerDeviceType.c_str());
240 return false;
241 }
242
243 auto deleteSlotTypeList = deleteSlotTypeListIt->second;
244 if (deleteSlotTypeList.find(slotType) == deleteSlotTypeList.end()) {
245 ANS_LOGD("deleteSlotTypeList no slottype:%{public}s, local:%{public}s, per:%{public}s",
246 slotType.c_str(), localDeviceType.c_str(), peerDeviceType.c_str());
247 return false;
248 }
249
250 return true;
251 }
252
253
SlotEnumToSring(const NotificationConstant::SlotType & slotType)254 std::string DistribuedSubscriber::SlotEnumToSring(const NotificationConstant::SlotType& slotType)
255 {
256 std::string type;
257 switch (slotType) {
258 case NotificationConstant::SlotType::SOCIAL_COMMUNICATION:
259 type = "SOCIAL_COMMUNICATION";
260 break;
261 case NotificationConstant::SlotType::SERVICE_REMINDER:
262 type = "SERVICE_REMINDER";
263 break;
264 case NotificationConstant::SlotType::CONTENT_INFORMATION:
265 type = "CONTENT_INFORMATION";
266 break;
267 case NotificationConstant::SlotType::OTHER:
268 type = "OTHER";
269 break;
270 case NotificationConstant::SlotType::CUSTOM:
271 type = "CUSTOM";
272 break;
273 case NotificationConstant::SlotType::LIVE_VIEW:
274 type = "LIVE_VIEW";
275 break;
276 case NotificationConstant::SlotType::CUSTOMER_SERVICE:
277 type = "CUSTOMER_SERVICE";
278 break;
279 case NotificationConstant::SlotType::EMERGENCY_INFORMATION:
280 type = "EMERGENCY_INFORMATION";
281 break;
282 case NotificationConstant::SlotType::ILLEGAL_TYPE:
283 type = "ILLEGAL_TYPE";
284 break;
285 default:
286 break;
287 }
288 return type;
289 }
290 }
291 }
292