1 /* 2 * Copyright (c) 2021-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 #ifndef BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_SERVICES_ANS_INCLUDE_NOTIFICATION_FLOW_CONTROL_SERVICE_H 17 #define BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_SERVICES_ANS_INCLUDE_NOTIFICATION_FLOW_CONTROL_SERVICE_H 18 19 #include <ctime> 20 #include <list> 21 #include <memory> 22 #include <mutex> 23 24 #include "errors.h" 25 #include "singleton.h" 26 #include "ans_const_define.h" 27 #include "notification_record.h" 28 #include "notification_analytics_util.h" 29 #include "ffrt.h" 30 31 namespace OHOS { 32 namespace Notification { 33 struct FlowControlThreshold { 34 uint32_t maxCreateNumPerSecond = MAX_CREATE_NUM_PERSECOND; 35 uint32_t maxUpdateNumPerSecond = MAX_UPDATE_NUM_PERSECOND; 36 uint32_t maxCreateNumPerSecondPerApp = MAX_CREATE_NUM_PERSECOND_PERAPP; 37 uint32_t maxUpdateNumPerSecondPerApp = MAX_UPDATE_NUM_PERSECOND_PERAPP; 38 }; 39 40 struct FlowControlErrMsg { 41 std::string msg; 42 EventSceneId sceneId; 43 EventBranchId EventBranchId; 44 ErrCode errCode; 45 }; 46 47 enum FlowControlSceneType { 48 GLOBAL_SYSTEM_NORMAL_CREATE, 49 GLOBAL_SYSTEM_NORMAL_UPDATE, 50 GLOBAL_SYSTEM_LIVEVIEW_CREATE, 51 GLOBAL_SYSTEM_LIVEVIEW_UPDATE, 52 GLOBAL_THIRD_PART_NORMAL_CREATE, 53 GLOBAL_THIRD_PART_NORMAL_UPDATE, 54 GLOBAL_THIRD_PART_LIVEVIEW_CREATE, 55 GLOBAL_THIRD_PART_LIVEVIEW_UPDATE, 56 CALLER_SYSTEM_NORMAL_CREATE, 57 CALLER_SYSTEM_NORMAL_UPDATE, 58 CALLER_SYSTEM_LIVEVIEW_CREATE, 59 CALLER_SYSTEM_LIVEVIEW_UPDATE, 60 CALLER_THIRD_PART_NORMAL_CREATE, 61 CALLER_THIRD_PART_NORMAL_UPDATE, 62 CALLER_THIRD_PART_LIVEVIEW_CREATE, 63 CALLER_THIRD_PART_LIVEVIEW_UPDATE, 64 }; 65 66 class GlobalFlowController { 67 public: 68 using TimePoint = std::chrono::system_clock::time_point; GlobalFlowController(const uint32_t threshold,const FlowControlErrMsg & errMsg)69 GlobalFlowController(const uint32_t threshold, const FlowControlErrMsg& errMsg) 70 : threshold_(threshold), errMsg_(errMsg) {} 71 72 /** 73 * @brief Flow control for all apps. 74 * 75 * @param record Notification record. User should ensure that record is not nullptr. 76 * @param now Current time. 77 * @return Returns ERR_OK when the call frequency doesn't reach the threshold. 78 */ 79 ErrCode FlowControl(const std::shared_ptr<NotificationRecord> record, const TimePoint &now); 80 81 /** 82 * @brief Add a timestamp to flow control list. 83 * 84 * @param now Current time. 85 */ 86 void RecordTimestamp(const TimePoint &now); 87 88 private: 89 uint32_t threshold_; 90 FlowControlErrMsg errMsg_; 91 ffrt::mutex globalFlowControllerMutex_; 92 std::list<TimePoint> globalFlowControllerList_; 93 }; 94 95 class CallerFlowController { 96 public: 97 using TimePoint = std::chrono::system_clock::time_point; CallerFlowController(const uint32_t threshold,const FlowControlErrMsg & errMsg)98 CallerFlowController(const uint32_t threshold, const FlowControlErrMsg& errMsg) 99 : threshold_(threshold), errMsg_(errMsg) {} 100 101 /** 102 * @brief Flow control for specified app which owns the notification. 103 * 104 * @param record Notification record. User should ensure that record is not nullptr. 105 * @param callingUid Uid of caller. 106 * @param now Current time. 107 * @return Returns ERR_OK when the call frequency doesn't reach the threshold. 108 */ 109 ErrCode FlowControl( 110 const std::shared_ptr<NotificationRecord> record, const int32_t callingUid, const TimePoint &now); 111 112 /** 113 * @brief Add a timestamp to flow control list. 114 * 115 * @param record Notification record to acquire owner uid of notification. User should ensure that record is not nullptr. 116 * @param callingUid Uid of caller. 117 * @param now Current time. 118 */ 119 void RecordTimestamp( 120 const std::shared_ptr<NotificationRecord> record, const int32_t callingUid, const TimePoint &now); 121 122 /** 123 * @brief Remove expired appliacation record. 124 * 125 * @param now Current time. 126 */ 127 void RemoveExpired(const TimePoint &now); 128 private: 129 uint32_t threshold_; 130 FlowControlErrMsg errMsg_; 131 ffrt::mutex callerFlowControllerMutex_; 132 std::map<int32_t, std::shared_ptr<std::list<TimePoint>>> callerFlowControllerMapper_; 133 }; 134 135 class FlowControlService { 136 public: 137 DISALLOW_COPY_AND_MOVE(FlowControlService); 138 static FlowControlService& GetInstance(); 139 140 /** 141 * @brief Flow control total entrance. 142 * 143 * @param record Notification record. User should ensure that record is not nullptr. 144 * @param callingUid Uid of caller. 145 * @param isNotificationExists true when update notification and false when create notification. 146 */ 147 ErrCode FlowControl( 148 const std::shared_ptr<NotificationRecord> record, const int32_t callingUid, bool isNotificationExists); 149 150 private: 151 FlowControlService(); 152 void InitGlobalFlowControl(); 153 void InitCallerFlowControl(); 154 std::pair<FlowControlSceneType, FlowControlSceneType> GetSceneTypePair( 155 const std::shared_ptr<NotificationRecord> record, bool isNotificationExists); 156 157 private: 158 FlowControlThreshold threshold_; 159 std::map<FlowControlSceneType, std::shared_ptr<GlobalFlowController>> globalFlowControllerMapper_; 160 std::map<FlowControlSceneType, std::shared_ptr<CallerFlowController>> callerFlowControllerMapper_; 161 }; 162 } // namespace Notification 163 } // namespace OHOS 164 165 #endif // BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_SERVICES_ANS_INCLUDE_NOTIFICATION_FLOW_CONTROL_SERVICE_H