1 /*
2 * Copyright (c) 2021-2023 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 "advanced_notification_service.h"
17 #include "notification_rdb_data_mgr.h"
18
19 #include <cstdint>
20 #include <functional>
21 #include <iomanip>
22 #include <sstream>
23 #include <sys/statfs.h>
24
25 #include "access_token_helper.h"
26 #include "ans_inner_errors.h"
27 #include "ans_log_wrapper.h"
28 #include "ans_permission_def.h"
29 #include "common_event_manager.h"
30 #include "common_event_support.h"
31 #include "event_report.h"
32 #include "errors.h"
33 #include "common_event_manager.h"
34 #include "common_event_support.h"
35 #include "hitrace_meter_adapter.h"
36 #include "ipc_skeleton.h"
37 #include "directory_ex.h"
38
39 #include "advanced_notification_inline.h"
40
41 namespace OHOS {
42 namespace Notification {
43
44 static int32_t USER_DATA_SIZE_REPORT_INTERVAL = 24 * NotificationConstant::HOUR_TO_MS;
45 static int64_t lastReportTime_ = 0;
46 const std::string ANS_COMPONENT_NAME = "distributed_notification_service";
47 const std::string ANS_PARTITION_NAME = "/data";
48 const std::vector<std::string> ANS_FOLDER_PATHS = {
49 "/data/service/el1/public/database/notification_service"
50 };
51
SendSubscribeHiSysEvent(int32_t pid,int32_t uid,const sptr<NotificationSubscribeInfo> & info,ErrCode errCode)52 void AdvancedNotificationService::SendSubscribeHiSysEvent(int32_t pid, int32_t uid,
53 const sptr<NotificationSubscribeInfo> &info, ErrCode errCode)
54 {
55 EventInfo eventInfo;
56 eventInfo.pid = pid;
57 eventInfo.uid = uid;
58 if (info != nullptr) {
59 ANS_LOGD("info is not nullptr.");
60 eventInfo.userId = info->GetAppUserId();
61 std::vector<std::string> appNames = info->GetAppNames();
62 eventInfo.bundleName = std::accumulate(appNames.begin(), appNames.end(), std::string(""),
63 [appNames](const std::string &bundleName, const std::string &str) {
64 return (str == appNames.front()) ? (bundleName + str) : (bundleName + "," + str);
65 });
66 }
67
68 if (errCode != ERR_OK) {
69 eventInfo.errCode = errCode;
70 EventReport::SendHiSysEvent(SUBSCRIBE_ERROR, eventInfo);
71 } else {
72 EventReport::SendHiSysEvent(SUBSCRIBE, eventInfo);
73 }
74 }
75
SendUnSubscribeHiSysEvent(int32_t pid,int32_t uid,const sptr<NotificationSubscribeInfo> & info)76 void AdvancedNotificationService::SendUnSubscribeHiSysEvent(int32_t pid, int32_t uid,
77 const sptr<NotificationSubscribeInfo> &info)
78 {
79 EventInfo eventInfo;
80 eventInfo.pid = pid;
81 eventInfo.uid = uid;
82 if (info != nullptr) {
83 eventInfo.userId = info->GetAppUserId();
84 std::vector<std::string> appNames = info->GetAppNames();
85 eventInfo.bundleName = std::accumulate(appNames.begin(), appNames.end(), std::string(""),
86 [appNames](const std::string &bundleName, const std::string &str) {
87 return (str == appNames.front()) ? (bundleName + str) : (bundleName + "," + str);
88 });
89 }
90
91 EventReport::SendHiSysEvent(UNSUBSCRIBE, eventInfo);
92 }
93
SendPublishHiSysEvent(const sptr<NotificationRequest> & request,ErrCode errCode)94 void AdvancedNotificationService::SendPublishHiSysEvent(const sptr<NotificationRequest> &request, ErrCode errCode)
95 {
96 if (request == nullptr) {
97 return;
98 }
99
100 EventInfo eventInfo;
101 eventInfo.notificationId = request->GetNotificationId();
102 eventInfo.contentType = static_cast<int32_t>(request->GetNotificationType());
103 eventInfo.bundleName = request->GetCreatorBundleName();
104 eventInfo.userId = request->GetCreatorUserId();
105 eventInfo.slotType = request->GetSlotType();
106 eventInfo.classification = request->GetClassification();
107 if (request->GetFlags() != nullptr) {
108 eventInfo.reminderFlags = request->GetFlags()->GetReminderFlags();
109 }
110 eventInfo.notificationControlFlags = request->GetNotificationControlFlags();
111 if (errCode != ERR_OK) {
112 eventInfo.errCode = errCode;
113 EventReport::SendHiSysEvent(PUBLISH_ERROR, eventInfo);
114 } else {
115 EventReport::SendHiSysEvent(PUBLISH, eventInfo);
116 }
117 }
118
SendCancelHiSysEvent(int32_t notificationId,const std::string & label,const sptr<NotificationBundleOption> & bundleOption,ErrCode errCode)119 void AdvancedNotificationService::SendCancelHiSysEvent(int32_t notificationId, const std::string &label,
120 const sptr<NotificationBundleOption> &bundleOption, ErrCode errCode)
121 {
122 if (bundleOption == nullptr || errCode != ERR_OK) {
123 ANS_LOGD("bundleOption is nullptr or not ok %{public}d.", errCode);
124 return;
125 }
126
127 EventInfo eventInfo;
128 eventInfo.notificationId = notificationId;
129 eventInfo.notificationLabel = label;
130 eventInfo.bundleName = bundleOption->GetBundleName();
131 eventInfo.uid = bundleOption->GetUid();
132 EventReport::SendHiSysEvent(CANCEL, eventInfo);
133 }
134
SendRemoveHiSysEvent(int32_t notificationId,const std::string & label,const sptr<NotificationBundleOption> & bundleOption,ErrCode errCode)135 void AdvancedNotificationService::SendRemoveHiSysEvent(int32_t notificationId, const std::string &label,
136 const sptr<NotificationBundleOption> &bundleOption, ErrCode errCode)
137 {
138 if (bundleOption == nullptr || errCode != ERR_OK) {
139 return;
140 }
141
142 EventInfo eventInfo;
143 eventInfo.notificationId = notificationId;
144 eventInfo.notificationLabel = label;
145 eventInfo.bundleName = bundleOption->GetBundleName();
146 eventInfo.uid = bundleOption->GetUid();
147 EventReport::SendHiSysEvent(REMOVE, eventInfo);
148 }
149
SendEnableNotificationHiSysEvent(const sptr<NotificationBundleOption> & bundleOption,bool enabled,ErrCode errCode)150 void AdvancedNotificationService::SendEnableNotificationHiSysEvent(const sptr<NotificationBundleOption> &bundleOption,
151 bool enabled, ErrCode errCode)
152 {
153 if (bundleOption == nullptr) {
154 return;
155 }
156
157 EventInfo eventInfo;
158 eventInfo.bundleName = bundleOption->GetBundleName();
159 eventInfo.uid = bundleOption->GetUid();
160 eventInfo.enable = enabled;
161 if (errCode != ERR_OK) {
162 eventInfo.errCode = errCode;
163 EventReport::SendHiSysEvent(ENABLE_NOTIFICATION_ERROR, eventInfo);
164 } else {
165 EventReport::SendHiSysEvent(ENABLE_NOTIFICATION, eventInfo);
166 }
167 }
168
SendEnableNotificationSlotHiSysEvent(const sptr<NotificationBundleOption> & bundleOption,const NotificationConstant::SlotType & slotType,bool enabled,ErrCode errCode)169 void AdvancedNotificationService::SendEnableNotificationSlotHiSysEvent(
170 const sptr<NotificationBundleOption> &bundleOption, const NotificationConstant::SlotType &slotType,
171 bool enabled, ErrCode errCode)
172 {
173 if (bundleOption == nullptr) {
174 return;
175 }
176
177 EventInfo eventInfo;
178 eventInfo.bundleName = bundleOption->GetBundleName();
179 eventInfo.uid = bundleOption->GetUid();
180 eventInfo.slotType = slotType;
181 eventInfo.enable = enabled;
182 if (errCode != ERR_OK) {
183 eventInfo.errCode = errCode;
184 EventReport::SendHiSysEvent(ENABLE_NOTIFICATION_SLOT_ERROR, eventInfo);
185 } else {
186 EventReport::SendHiSysEvent(ENABLE_NOTIFICATION_SLOT, eventInfo);
187 }
188 }
189
SendFlowControlOccurHiSysEvent(const std::shared_ptr<NotificationRecord> & record)190 void AdvancedNotificationService::SendFlowControlOccurHiSysEvent(const std::shared_ptr<NotificationRecord> &record)
191 {
192 if (record == nullptr || record->request == nullptr || record->bundleOption == nullptr) {
193 return;
194 }
195
196 EventInfo eventInfo;
197 eventInfo.notificationId = record->request->GetNotificationId();
198 eventInfo.bundleName = record->bundleOption->GetBundleName();
199 eventInfo.uid = record->bundleOption->GetUid();
200 EventReport::SendHiSysEvent(FLOW_CONTROL_OCCUR, eventInfo);
201 }
202
SendLiveViewUploadHiSysEvent(const std::shared_ptr<NotificationRecord> & record,int32_t uploadStatus)203 void AdvancedNotificationService::SendLiveViewUploadHiSysEvent(
204 const std::shared_ptr<NotificationRecord> &record, int32_t uploadStatus)
205 {
206 if (record == nullptr || record->request == nullptr ||
207 uploadStatus < UploadStatus::CREATE || uploadStatus > UploadStatus::END) {
208 return;
209 }
210
211 EventInfo eventInfo;
212 eventInfo.notificationId = record->request->GetNotificationId();
213 eventInfo.bundleName = record->request->GetCreatorBundleName();
214 eventInfo.contentType = static_cast<int32_t>(record->request->GetNotificationType());
215 eventInfo.operateFlag = uploadStatus;
216 EventReport::SendHiSysEvent(STATIC_LIVE_VIEW_UPLOAD, eventInfo);
217 }
218
SendUserDataSizeHisysevent()219 void NotificationDataMgr::SendUserDataSizeHisysevent()
220 {
221 auto now = std::chrono::duration_cast<std::chrono::milliseconds>(
222 std::chrono::system_clock::now().time_since_epoch()).count();
223 if (lastReportTime_ != 0 && abs(now - lastReportTime_) <= USER_DATA_SIZE_REPORT_INTERVAL) {
224 ANS_LOGD("no need report");
225 return;
226 }
227
228 ANS_LOGI("user data size hisysevent report");
229 lastReportTime_ = now;
230
231 UserDataSizeInfo userDataSizeInfo;
232 userDataSizeInfo.componentName = ANS_COMPONENT_NAME;
233 userDataSizeInfo.partitionName = ANS_PARTITION_NAME;
234 userDataSizeInfo.folderPath = ANS_FOLDER_PATHS;
235 userDataSizeInfo.folderSize = GetFileOrFolderSize(ANS_FOLDER_PATHS);
236 userDataSizeInfo.remainPartitionSize = GetRemainPartitionSize(ANS_PARTITION_NAME);
237
238 EventReport::SendHiSysEvent(userDataSizeInfo);
239 }
240
GetFileOrFolderSize(const std::vector<std::string> & paths)241 std::vector<std::uint64_t> NotificationDataMgr::GetFileOrFolderSize(const std::vector<std::string> &paths)
242 {
243 std::vector<std::uint64_t> folderSize;
244 for (auto path : paths) {
245 folderSize.emplace_back(OHOS::GetFolderSize(path));
246 }
247 return folderSize;
248 }
249
GetRemainPartitionSize(const std::string & partitionName)250 std::uint64_t NotificationDataMgr::GetRemainPartitionSize(const std::string &partitionName)
251 {
252 struct statfs stat;
253 if (statfs(partitionName.c_str(), &stat) != 0) {
254 return -1;
255 }
256 std::uint64_t blockSize = stat.f_bsize;
257 std::uint64_t freeSize = stat.f_bfree * blockSize;
258 constexpr double units = 1024.0;
259 return freeSize/(units * units);
260 }
261 } // namespace Notification
262 } // namespace OHOS
263