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 #ifndef NET_STATS_CACHED_H
17 #define NET_STATS_CACHED_H
18 
19 #include <algorithm>
20 #include <map>
21 #include <mutex>
22 #include <vector>
23 
24 #include "ffrt.h"
25 #include "net_push_stats_info.h"
26 #include "net_stats_callback.h"
27 #include "net_stats_info.h"
28 #include "netmanager_base_common_utils.h"
29 #include "safe_map.h"
30 
31 #include "ffrt_timer.h"
32 
33 namespace OHOS {
34 namespace NetManagerStandard {
35 class NetStatsCached {
36 public:
37     NetStatsCached() = default;
38     ~NetStatsCached() = default;
39     void ForceUpdateStats();
40 
41     void ForceDeleteStats(uint32_t uid);
42 
43     void ForceArchiveStats(uint32_t uid);
44 
45     int32_t StartCached();
46 
47     void SetCycleThreshold(uint32_t threshold);
48 
49     void GetUidStatsCached(std::vector<NetStatsInfo> &uidStatsInfo);
50 
51     void GetUidSimStatsCached(std::vector<NetStatsInfo> &uidSimStatsInfo);
52 
53     void GetUidPushStatsCached(std::vector<NetStatsInfo> &uidPushStatsInfo);
54 
55     void GetAllPushStatsCached(std::vector<NetStatsInfo> &uidPushStatsInfo);
56 
57     void GetIfaceStatsCached(std::vector<NetStatsInfo> &ifaceStatsInfo);
58 
59     void SetAppStats(const PushStatsInfo &info);
60 
61     void GetKernelStats(std::vector<NetStatsInfo> &statsInfo);
62 
SetTrafficThreshold(uint64_t threshold)63     inline void SetTrafficThreshold(uint64_t threshold)
64     {
65         trafficThreshold_ = threshold;
66     }
67 
SetDateThreshold(uint64_t threshold)68     inline void SetDateThreshold(uint64_t threshold)
69     {
70         cycleThreshold_ = threshold;
71     }
72 
SetCallbackManager(const std::shared_ptr<NetStatsCallback> & callbackManager)73     inline void SetCallbackManager(const std::shared_ptr<NetStatsCallback> &callbackManager)
74     {
75         stats_.SetNotifier(callbackManager);
76     }
77 
78     void Reset();
79 
80 private:
81     class CachedInfo {
82     public:
PushUidStats(NetStatsInfo & info)83         void PushUidStats(NetStatsInfo &info)
84         {
85             if (info.HasNoData()) {
86                 return;
87             }
88             info.date_ = CommonUtils::GetCurrentSecond();
89             uidStatsInfo_.push_back(info);
90             currentUidStats_ += info.GetStats();
91             if (netStatsCallbackManager_ != nullptr) {
92                 netStatsCallbackManager_->NotifyNetUidStatsChanged(info.iface_, info.uid_);
93             }
94         }
95 
PushUidSimStats(NetStatsInfo & info)96         void PushUidSimStats(NetStatsInfo &info)
97         {
98             if (info.HasNoData()) {
99                 return;
100             }
101             info.date_ = CommonUtils::GetCurrentSecond();
102             uidSimStatsInfo_.push_back(info);
103             currentUidSimStats_ += info.GetStats();
104             if (netStatsCallbackManager_ != nullptr) {
105                 netStatsCallbackManager_->NotifyNetUidStatsChanged(info.iface_, info.uid_);
106             }
107         }
108 
PushIfaceStats(NetStatsInfo & info)109         void PushIfaceStats(NetStatsInfo &info)
110         {
111             if (info.HasNoData()) {
112                 return;
113             }
114             info.date_ = CommonUtils::GetCurrentSecond();
115             ifaceStatsInfo_.push_back(info);
116             currentIfaceStats_ += info.GetStats();
117             if (netStatsCallbackManager_ != nullptr) {
118                 netStatsCallbackManager_->NotifyNetIfaceStatsChanged(info.iface_);
119             }
120         }
121 
GetUidStatsInfo()122         inline std::vector<NetStatsInfo> &GetUidStatsInfo()
123         {
124             return uidStatsInfo_;
125         }
126 
GetUidSimStatsInfo()127         inline std::vector<NetStatsInfo> &GetUidSimStatsInfo()
128         {
129             return uidSimStatsInfo_;
130         }
131 
GetIfaceStatsInfo()132         inline std::vector<NetStatsInfo> &GetIfaceStatsInfo()
133         {
134             return ifaceStatsInfo_;
135         }
136 
GetCurrentUidStats()137         inline uint64_t GetCurrentUidStats() const
138         {
139             return currentUidStats_;
140         }
141 
GetCurrentUidSimStats()142         inline uint64_t GetCurrentUidSimStats() const
143         {
144             return currentUidSimStats_;
145         }
146 
GetCurrentIfaceStats()147         inline uint64_t GetCurrentIfaceStats() const
148         {
149             return currentIfaceStats_;
150         }
151 
ResetUidStats()152         void ResetUidStats()
153         {
154             uidStatsInfo_.clear();
155             currentUidStats_ = 0;
156         }
157 
ResetUidStats(uint32_t uid)158         void ResetUidStats(uint32_t uid)
159         {
160             for (const auto &item : uidStatsInfo_) {
161                 if (item.uid_ == uid) {
162                     currentUidStats_ -= item.GetStats();
163                 }
164             }
165             uidStatsInfo_.erase(std::remove_if(uidStatsInfo_.begin(), uidStatsInfo_.end(),
166                                                [uid](const auto &item) { return item.uid_ == uid; }),
167                                 uidStatsInfo_.end());
168         }
169 
ResetUidSimStats()170         void ResetUidSimStats()
171         {
172             uidSimStatsInfo_.clear();
173             currentUidSimStats_ = 0;
174         }
175 
ResetUidSimStats(uint32_t uid)176         void ResetUidSimStats(uint32_t uid)
177         {
178             for (const auto &item : uidSimStatsInfo_) {
179                 if (item.uid_ == uid) {
180                     currentUidSimStats_ -= item.GetStats();
181                 }
182             }
183             uidSimStatsInfo_.erase(std::remove_if(uidSimStatsInfo_.begin(), uidSimStatsInfo_.end(),
184                                                   [uid](const auto &item) { return item.uid_ == uid; }),
185                                    uidSimStatsInfo_.end());
186         }
187 
ResetIfaceStats()188         void ResetIfaceStats()
189         {
190             ifaceStatsInfo_.clear();
191             currentIfaceStats_ = 0;
192         }
193 
SetNotifier(const std::shared_ptr<NetStatsCallback> & callbackManager)194         inline void SetNotifier(const std::shared_ptr<NetStatsCallback> &callbackManager)
195         {
196             netStatsCallbackManager_ = callbackManager;
197         }
198 
199     private:
200         uint64_t currentUidStats_ = 0;
201         uint64_t currentUidSimStats_ = 0;
202         uint64_t currentIfaceStats_ = 0;
203         std::vector<NetStatsInfo> uidStatsInfo_;
204         std::vector<NetStatsInfo> uidSimStatsInfo_;
205         std::vector<NetStatsInfo> ifaceStatsInfo_;
206         std::shared_ptr<NetStatsCallback> netStatsCallbackManager_ = nullptr;
207     };
208 
209     static constexpr uint32_t DEFAULT_CACHE_CYCLE_MS = 30 * 60 * 1000;
210     static constexpr uint64_t DEFAULT_TRAFFIC_STATISTICS_THRESHOLD_BYTES = 2 * 1024 * 1024;
211     static constexpr uint64_t DEFAULT_DATA_CYCLE_S = 180 * 24 * 60 * 60;
212     static constexpr uint64_t CACHE_DATE_TIME_S = 1 * 24 * 60 * 60;
213     static constexpr uint64_t STATS_PACKET_CYCLE_MS = 1 * 60 * 60 * 1000;
214 
215     CachedInfo stats_;
216     ffrt::mutex lock_;
217     bool isForce_ = false;
218     std::unique_ptr<FfrtTimer> cacheTimer_ = nullptr;
219     std::unique_ptr<FfrtTimer> writeTimer_ = nullptr;
220     uint32_t cycleThreshold_ = DEFAULT_CACHE_CYCLE_MS;
221     uint64_t trafficThreshold_ = DEFAULT_TRAFFIC_STATISTICS_THRESHOLD_BYTES;
222     uint64_t dateCycle_ = DEFAULT_DATA_CYCLE_S;
223     std::vector<NetStatsInfo> uidPushStatsInfo_;
224     std::vector<NetStatsInfo> allPushStatsInfo_;
225     std::vector<NetStatsInfo> lastUidStatsInfo_;
226     std::vector<NetStatsInfo> lastUidSimStatsInfo_;
227     std::map<std::string, NetStatsInfo> lastIfaceStatsMap_;
228     std::atomic<int64_t> uninstalledUid_ = -1;
229     SafeMap<std::string, std::string> ifaceNameIdentMap_;
230 
231     void LoadIfaceNameIdentMaps();
232 
233     void CacheStats();
234     void CacheUidStats();
235     void CacheUidSimStats();
236     void CacheIfaceStats();
237     void CacheAppStats();
238 
239     void WriteStats();
240     void WriteUidStats();
241     void WriteUidSimStats();
242     void WriteIfaceStats();
243 
244     NetStatsInfo GetIncreasedStats(const NetStatsInfo &info);
245 
246     NetStatsInfo GetIncreasedSimStats(const NetStatsInfo &info);
247 
CheckUidStor()248     inline bool CheckUidStor()
249     {
250         return stats_.GetCurrentUidStats() >= trafficThreshold_;
251     }
252 
CheckUidSimStor()253     inline bool CheckUidSimStor()
254     {
255         return stats_.GetCurrentUidSimStats() >= trafficThreshold_;
256     }
257 
CheckIfaceStor()258     inline bool CheckIfaceStor()
259     {
260         return stats_.GetCurrentIfaceStats() >= trafficThreshold_;
261     }
262 };
263 } // namespace NetManagerStandard
264 } // namespace OHOS
265 
266 #endif // NET_STATS_CACHED_H
267