• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 "net_stats_cached.h"
17 
18 #include <initializer_list>
19 #include <list>
20 #include <pthread.h>
21 
22 #include "net_conn_client.h"
23 #include "net_mgr_log_wrapper.h"
24 #include "net_stats_constants.h"
25 #include "net_stats_data_handler.h"
26 #include "net_stats_database_defines.h"
27 #include "net_stats_database_helper.h"
28 #include "netsys_controller.h"
29 #include "bpf_stats.h"
30 #include "ffrt_inner.h"
31 
32 namespace OHOS {
33 namespace NetManagerStandard {
34 using namespace NetStatsDatabaseDefines;
35 namespace {
36 constexpr const char *IFACE_LO = "lo";
37 constexpr const char *INSTALL_SOURCE_DEFAULT = "default";
38 const std::string CELLULAR_IFACE_NAME = "rmnet";
39 } // namespace
40 const int8_t RETRY_TIME = 3;
41 
StartCached()42 int32_t NetStatsCached::StartCached()
43 {
44     auto ret = CreatNetStatsTables();
45     if (ret != NETMANAGER_SUCCESS) {
46         NETMGR_LOG_E("CreatNetStatsTables error. ret: %{public}d", ret);
47         return ret;
48     }
49 #ifndef UNITTEST_FORBID_FFRT
50     cacheTimer_ = std::make_unique<FfrtTimer>();
51     writeTimer_ = std::make_unique<FfrtTimer>();
52     cacheTimer_->StartPro(cycleThreshold_, this, [](void *netStatsCachedPtr) -> void {
53         if (netStatsCachedPtr != nullptr) {
54             NetStatsCached *netStatsCached = reinterpret_cast<NetStatsCached *>(netStatsCachedPtr);
55             netStatsCached->CacheStats();
56         } else {
57             NETMGR_LOG_E("not NetStatsCached obj");
58         }
59     });
60     writeTimer_->StartPro(STATS_PACKET_CYCLE_MS, this, [](void *netStatsCachedPtr) -> void {
61         if (netStatsCachedPtr != nullptr) {
62             NetStatsCached *netStatsCached = reinterpret_cast<NetStatsCached *>(netStatsCachedPtr);
63             netStatsCached->WriteStats();
64         } else {
65             NETMGR_LOG_E("not NetStatsCached obj");
66         }
67     });
68 #endif
69     return ret;
70 }
71 
CreatNetStatsTables()72 int32_t NetStatsCached::CreatNetStatsTables()
73 {
74     auto helper = std::make_unique<NetStatsDatabaseHelper>(NET_STATS_DATABASE_PATH);
75     int8_t curRetryTimes = 0;
76     int32_t ret = -1;
77     while (curRetryTimes < RETRY_TIME) {
78         NETMGR_LOG_I("Create table times: %{public}d", curRetryTimes + 1);
79         ret = helper->CreateTable(VERSION_TABLE, VERSION_TABLE_CREATE_PARAM);
80         if (ret != NETMANAGER_SUCCESS) {
81             NETMGR_LOG_E("Create version table failed");
82             curRetryTimes++;
83             continue;
84         }
85         ret = helper->CreateTable(UID_TABLE, UID_TABLE_CREATE_PARAM);
86         if (ret != NETMANAGER_SUCCESS) {
87             NETMGR_LOG_E("Create uid table failed");
88             curRetryTimes++;
89             continue;
90         }
91         ret = helper->CreateTable(IFACE_TABLE, IFACE_TABLE_CREATE_PARAM);
92         if (ret != NETMANAGER_SUCCESS) {
93             NETMGR_LOG_E("Create iface table failed");
94             curRetryTimes++;
95             continue;
96         }
97         ret = helper->CreateTable(UID_SIM_TABLE, UID_SIM_TABLE_CREATE_PARAM);
98         if (ret != NETMANAGER_SUCCESS) {
99             NETMGR_LOG_E("Create uid_sim table failed");
100             curRetryTimes++;
101             continue;
102         }
103         break;
104     }
105     if (ret != NETMANAGER_SUCCESS) {
106         NETMGR_LOG_E("Create table failed");
107         return STATS_ERR_CREATE_TABLE_FAIL;
108     }
109     helper->Upgrade();
110     return NETMANAGER_SUCCESS;
111 }
112 
GetUidStatsCached(std::vector<NetStatsInfo> & uidStatsInfo)113 void NetStatsCached::GetUidStatsCached(std::vector<NetStatsInfo> &uidStatsInfo)
114 {
115     std::lock_guard<ffrt::mutex> lock(lock_);
116     uidStatsInfo.insert(uidStatsInfo.end(), stats_.GetUidStatsInfo().begin(), stats_.GetUidStatsInfo().end());
117 }
118 
GetUidSimStatsCached(std::vector<NetStatsInfo> & uidSimStatsInfo)119 void NetStatsCached::GetUidSimStatsCached(std::vector<NetStatsInfo> &uidSimStatsInfo)
120 {
121     std::lock_guard<ffrt::mutex> lock(lock_);
122     std::vector<NetStatsInfo> tmpList;
123     std::transform(stats_.GetUidSimStatsInfo().begin(), stats_.GetUidSimStatsInfo().end(), std::back_inserter(tmpList),
124                    [](NetStatsInfo &info) {
125                        NetStatsInfo tmpInfo = info;
126                        return tmpInfo;
127                    });
128     tmpList.erase(std::remove_if(tmpList.begin(), tmpList.end(), [](const auto &item) {
129                       return item.flag_ <= STATS_DATA_FLAG_DEFAULT || item.flag_ >= STATS_DATA_FLAG_LIMIT;
130                   }), tmpList.end());
131     std::transform(tmpList.begin(), tmpList.end(), std::back_inserter(uidSimStatsInfo), [](NetStatsInfo &info) {
132         if (info.flag_ == STATS_DATA_FLAG_SIM_BASIC) {
133             info.uid_ = Sim_UID;
134         } else if (info.flag_ == STATS_DATA_FLAG_SIM2_BASIC) {
135             info.uid_ = SIM2_UID;
136         }
137         return info;
138     });
139 }
140 
GetUidPushStatsCached(std::vector<NetStatsInfo> & uidPushStatsInfo)141 void NetStatsCached::GetUidPushStatsCached(std::vector<NetStatsInfo> &uidPushStatsInfo)
142 {
143     std::lock_guard<ffrt::mutex> lock(lock_);
144     uidPushStatsInfo.insert(uidPushStatsInfo.end(), uidPushStatsInfo_.begin(), uidPushStatsInfo_.end());
145 }
146 
GetAllPushStatsCached(std::vector<NetStatsInfo> & uidPushStatsInfo)147 void NetStatsCached::GetAllPushStatsCached(std::vector<NetStatsInfo> &uidPushStatsInfo)
148 {
149     std::lock_guard<ffrt::mutex> lock(lock_);
150     uidPushStatsInfo.insert(uidPushStatsInfo.end(), allPushStatsInfo_.begin(), allPushStatsInfo_.end());
151 }
152 
GetIfaceStatsCached(std::vector<NetStatsInfo> & ifaceStatsInfo)153 void NetStatsCached::GetIfaceStatsCached(std::vector<NetStatsInfo> &ifaceStatsInfo)
154 {
155     std::lock_guard<ffrt::mutex> lock(lock_);
156     ifaceStatsInfo.insert(ifaceStatsInfo.end(), stats_.GetIfaceStatsInfo().begin(), stats_.GetIfaceStatsInfo().end());
157 }
158 
SetAppStats(const PushStatsInfo & info)159 void NetStatsCached::SetAppStats(const PushStatsInfo &info)
160 {
161     std::lock_guard<ffrt::mutex> lock(lock_);
162     NetStatsInfo stats;
163     stats.uid_ = info.uid_;
164     stats.iface_ = info.iface_;
165     stats.date_ = info.endTime_;
166     stats.rxBytes_ = info.rxBytes_;
167     stats.txBytes_ = info.txBytes_;
168     stats.rxPackets_ = info.rxBytes_ > 0 ? 1 : 0;
169     stats.txPackets_ = info.txBytes_ > 0 ? 1 : 0;
170     if (info.netBearType_ == BEARER_CELLULAR) {
171         stats.ident_ = std::to_string(info.simId_);
172     }
173     NETMGR_LOG_D("SetAppStats info=%{public}s", stats.UidData().c_str());
174     uidPushStatsInfo_.push_back(std::move(stats));
175 }
176 
GetKernelStats(std::vector<NetStatsInfo> & statsInfo)177 void NetStatsCached::GetKernelStats(std::vector<NetStatsInfo> &statsInfo)
178 {
179     std::lock_guard<ffrt::mutex> lock(lock_);
180     GetKernelUidStats(statsInfo);
181     GetKernelUidSimStats(statsInfo);
182 }
183 
GetIncreasedStats(const NetStatsInfo & info)184 NetStatsInfo NetStatsCached::GetIncreasedStats(const NetStatsInfo &info)
185 {
186     auto findRet = std::find_if(lastUidStatsInfo_.begin(), lastUidStatsInfo_.end(),
187                                 [&info](const NetStatsInfo &lastInfo) { return info.Equals(lastInfo); });
188     if (findRet == lastUidStatsInfo_.end()) {
189         return info;
190     }
191     return info - *findRet;
192 }
193 
GetIncreasedSimStats(const NetStatsInfo & info)194 NetStatsInfo NetStatsCached::GetIncreasedSimStats(const NetStatsInfo &info)
195 {
196     auto findRet = std::find_if(lastUidSimStatsInfo_.begin(), lastUidSimStatsInfo_.end(),
197                                 [&info](const NetStatsInfo &lastInfo) { return info.Equals(lastInfo); });
198     if (findRet == lastUidSimStatsInfo_.end()) {
199         return info;
200     }
201     return info - *findRet;
202 }
203 
CacheUidStats()204 void NetStatsCached::CacheUidStats()
205 {
206     std::vector<NetStatsInfo> statsInfos;
207     NetsysController::GetInstance().GetAllStatsInfo(statsInfos);
208     if (statsInfos.empty()) {
209         NETMGR_LOG_W("No stats need to save");
210         return;
211     }
212 
213     ifaceNameIdentMap_.Iterate([&statsInfos](const std::string &k, const std::string &v) {
214         std::for_each(statsInfos.begin(), statsInfos.end(), [&k, &v](NetStatsInfo &item) {
215             if (item.iface_ == k) {
216                 item.ident_ = v;
217             }
218         });
219     });
220 
221     std::for_each(statsInfos.begin(), statsInfos.end(), [this](NetStatsInfo &info) {
222         if (info.iface_ == IFACE_LO) {
223             return;
224         }
225         auto findRet = std::find_if(lastUidStatsInfo_.begin(), lastUidStatsInfo_.end(),
226                                     [this, &info](const NetStatsInfo &lastInfo) { return info.Equals(lastInfo); });
227         if (findRet == lastUidStatsInfo_.end()) {
228             stats_.PushUidStats(info);
229             return;
230         }
231         auto currentStats = info - *findRet;
232         stats_.PushUidStats(currentStats);
233     });
234     lastUidStatsInfo_.swap(statsInfos);
235 }
236 
CacheAppStats()237 void NetStatsCached::CacheAppStats()
238 {
239     std::vector<NetStatsInfo> pushInfos;
240     std::for_each(uidPushStatsInfo_.begin(), uidPushStatsInfo_.end(), [&pushInfos](NetStatsInfo &info) {
241         auto findRet = std::find_if(pushInfos.begin(), pushInfos.end(),
242                                     [&info](const NetStatsInfo &item) { return info.Equals(item); });
243         if (findRet == pushInfos.end()) {
244             pushInfos.push_back(info);
245             return;
246         }
247         *findRet += info;
248     });
249     std::for_each(pushInfos.begin(), pushInfos.end(), [this](auto &item) {
250         stats_.PushUidStats(item);
251         auto findRet = std::find_if(allPushStatsInfo_.begin(), allPushStatsInfo_.end(),
252                                     [&item](const NetStatsInfo &info) {
253                                         return info.Equals(item) && info.ident_ == item.ident_;
254                                     });
255         if (findRet == allPushStatsInfo_.end()) {
256             allPushStatsInfo_.push_back(item);
257             return;
258         }
259         *findRet += item;
260     });
261     uidPushStatsInfo_.clear();
262 }
263 
CacheUidSimStats()264 void NetStatsCached::CacheUidSimStats()
265 {
266     std::vector<NetStatsInfo> statsInfos;
267     NetsysController::GetInstance().GetAllSimStatsInfo(statsInfos);
268     if (statsInfos.empty()) {
269         NETMGR_LOG_W("No stats need to save");
270         return;
271     }
272 
273     ifaceNameIdentMap_.Iterate([&statsInfos](const std::string &k, const std::string &v) {
274         std::for_each(statsInfos.begin(), statsInfos.end(), [&k, &v](NetStatsInfo &item) {
275             if (item.iface_ == k) {
276                 item.ident_ = v;
277             }
278         });
279     });
280     uidStatsFlagMap_.Iterate([&statsInfos](const uint32_t &k, const NetStatsDataFlag &v) {
281         std::for_each(statsInfos.begin(), statsInfos.end(), [&k, &v](NetStatsInfo &item) {
282             if (item.uid_ == k) {
283                 item.flag_ = v;
284             }
285         });
286     });
287 
288     std::for_each(statsInfos.begin(), statsInfos.end(), [this](NetStatsInfo &info) {
289         if (info.iface_ == IFACE_LO) {
290             return;
291         }
292         if (info.flag_ <= STATS_DATA_FLAG_DEFAULT || info.flag_ >= STATS_DATA_FLAG_LIMIT) {
293             info.flag_ = GetUidStatsFlag(info.uid_);
294         }
295         auto findRet = std::find_if(lastUidSimStatsInfo_.begin(), lastUidSimStatsInfo_.end(),
296                                     [this, &info](const NetStatsInfo &lastInfo) { return info.Equals(lastInfo); });
297         if (findRet == lastUidSimStatsInfo_.end()) {
298             stats_.PushUidSimStats(info);
299             return;
300         }
301         auto currentStats = info - *findRet;
302         stats_.PushUidSimStats(currentStats);
303     });
304     lastUidSimStatsInfo_.swap(statsInfos);
305 }
306 
CacheIfaceStats()307 void NetStatsCached::CacheIfaceStats()
308 {
309     std::vector<std::string> ifNameList = NetsysController::GetInstance().InterfaceGetList();
310     std::for_each(ifNameList.begin(), ifNameList.end(), [this](const auto &ifName) {
311         if (ifName == IFACE_LO) {
312             return;
313         }
314         NetStatsInfo statsInfo;
315         statsInfo.iface_ = ifName;
316         NetsysController::GetInstance().GetIfaceStats(statsInfo.rxBytes_,
317                                                       static_cast<uint32_t>(StatsType::STATS_TYPE_RX_BYTES), ifName);
318         NetsysController::GetInstance().GetIfaceStats(statsInfo.rxPackets_,
319                                                       static_cast<uint32_t>(StatsType::STATS_TYPE_RX_PACKETS), ifName);
320         NetsysController::GetInstance().GetIfaceStats(statsInfo.txBytes_,
321                                                       static_cast<uint32_t>(StatsType::STATS_TYPE_TX_BYTES), ifName);
322         NetsysController::GetInstance().GetIfaceStats(statsInfo.txPackets_,
323                                                       static_cast<uint32_t>(StatsType::STATS_TYPE_TX_PACKETS), ifName);
324         auto findRet = lastIfaceStatsMap_.find(ifName);
325         if (findRet == lastIfaceStatsMap_.end()) {
326             stats_.PushIfaceStats(statsInfo);
327             lastIfaceStatsMap_[ifName] = statsInfo;
328             return;
329         }
330         auto currentStats = statsInfo - findRet->second;
331         stats_.PushIfaceStats(currentStats);
332         lastIfaceStatsMap_[ifName] = statsInfo;
333     });
334 }
335 
CacheStats()336 void NetStatsCached::CacheStats()
337 {
338     std::lock_guard<ffrt::mutex> lock(lock_);
339     CacheUidStats();
340     CacheAppStats();
341     CacheUidSimStats();
342     CacheIfaceStats();
343 #ifdef SUPPORT_NETWORK_SHARE
344     CacheIptablesStats();
345 #endif
346 }
347 
WriteStats()348 void NetStatsCached::WriteStats()
349 {
350     std::lock_guard<ffrt::mutex> lock(lock_);
351     WriteUidStats();
352     WriteUidSimStats();
353     WriteIfaceStats();
354 #ifdef SUPPORT_NETWORK_SHARE
355     WriteIptablesStats();
356     writeDate_ = CommonUtils::GetCurrentSecond();
357 #endif
358 }
359 
360 #ifdef SUPPORT_NETWORK_SHARE
GetWriteDateTime()361 uint64_t NetStatsCached::GetWriteDateTime()
362 {
363     return writeDate_;
364 }
365 #endif
366 
WriteIfaceStats()367 void NetStatsCached::WriteIfaceStats()
368 {
369     if (!(CheckIfaceStor() || isForce_)) {
370         return;
371     }
372     auto handler = std::make_unique<NetStatsDataHandler>();
373     handler->WriteStatsData(stats_.GetIfaceStatsInfo(), NetStatsDatabaseDefines::IFACE_TABLE);
374     handler->DeleteByDate(NetStatsDatabaseDefines::IFACE_TABLE, 0, CommonUtils::GetCurrentSecond() - dateCycle_);
375     stats_.ResetIfaceStats();
376 }
377 
WriteUidStats()378 void NetStatsCached::WriteUidStats()
379 {
380     if (!(CheckUidStor() || isForce_)) {
381         return;
382     }
383     std::for_each(stats_.GetUidStatsInfo().begin(), stats_.GetUidStatsInfo().end(), [this](NetStatsInfo &info) {
384         if (info.uid_ == uninstalledUid_) {
385             info.flag_ = STATS_DATA_FLAG_UNINSTALLED;
386         }
387     });
388     auto handler = std::make_unique<NetStatsDataHandler>();
389     handler->WriteStatsData(stats_.GetUidStatsInfo(), NetStatsDatabaseDefines::UID_TABLE);
390     handler->DeleteByDate(NetStatsDatabaseDefines::UID_TABLE, 0, CommonUtils::GetCurrentSecond() - dateCycle_);
391     stats_.ResetUidStats();
392 }
393 
WriteUidSimStats()394 void NetStatsCached::WriteUidSimStats()
395 {
396     if (!(CheckUidSimStor() || isForce_)) {
397         return;
398     }
399     std::for_each(stats_.GetUidSimStatsInfo().begin(), stats_.GetUidSimStatsInfo().end(), [this](NetStatsInfo &info) {
400         if (info.uid_ == uninstalledUid_) {
401             info.flag_ = STATS_DATA_FLAG_UNINSTALLED;
402         }
403     });
404     auto handler = std::make_unique<NetStatsDataHandler>();
405     handler->WriteStatsData(stats_.GetUidSimStatsInfo(), NetStatsDatabaseDefines::UID_SIM_TABLE);
406     handler->DeleteByDate(NetStatsDatabaseDefines::UID_SIM_TABLE, 0, CommonUtils::GetCurrentSecond() - dateCycle_);
407     stats_.ResetUidSimStats();
408 }
409 
410 #ifdef SUPPORT_NETWORK_SHARE
WriteIptablesStats()411 void NetStatsCached::WriteIptablesStats()
412 {
413     if (!(CheckIptablesStor() || isForce_)) {
414         return;
415     }
416     auto handler = std::make_unique<NetStatsDataHandler>();
417     handler->WriteStatsData(stats_.GetIptablesStatsInfo(), NetStatsDatabaseDefines::UID_TABLE);
418     handler->DeleteByDate(NetStatsDatabaseDefines::UID_TABLE, 0, CommonUtils::GetCurrentSecond() - dateCycle_);
419     stats_.ResetIptablesStats();
420 }
421 #endif
422 
LoadIfaceNameIdentMaps()423 void NetStatsCached::LoadIfaceNameIdentMaps()
424 {
425     int32_t ret = NetConnClient::GetInstance().GetIfaceNameIdentMaps(NetBearType::BEARER_CELLULAR, ifaceNameIdentMap_);
426     if (ret != NETMANAGER_SUCCESS) {
427         NETMGR_LOG_E("GetIfaceNameIdentMaps error. ret=%{public}d", ret);
428     }
429 }
430 
SetCycleThreshold(uint32_t threshold)431 void NetStatsCached::SetCycleThreshold(uint32_t threshold)
432 {
433     NETMGR_LOG_D("Current cycle threshold has changed current is : %{public}d", threshold);
434     cycleThreshold_ = threshold;
435 #ifndef UNITTEST_FORBID_FFRT
436     cacheTimer_ = std::make_unique<FfrtTimer>();
437     cacheTimer_->Start(cycleThreshold_, [this]() { CacheStats(); });
438 #endif
439 }
440 
ForceUpdateStats()441 void NetStatsCached::ForceUpdateStats()
442 {
443     isForce_ = true;
444     std::function<void()> netCachedStats = [this] () {
445         isExec_ = true;
446         CacheStats();
447         WriteStats();
448         isForce_ = false;
449         LoadIfaceNameIdentMaps();
450         isExec_ = false;
451     };
452     if (!isExec_) {
453         ffrt::submit(std::move(netCachedStats), {}, {}, ffrt::task_attr().name("NetCachedStats"));
454     }
455 }
456 
ForceArchiveStats(uint32_t uid)457 ffrt::task_handle NetStatsCached::ForceArchiveStats(uint32_t uid)
458 {
459     std::function<void()> netCachedStats = [this, uid]() {
460         CacheStats();
461         {
462             std::lock_guard<ffrt::mutex> lock(lock_);
463             isForce_ = true;
464             uninstalledUid_ = uid;
465             WriteUidStats();
466             WriteUidSimStats();
467             uninstalledUid_ = -1;
468             isForce_ = false;
469         }
470         DeleteUidStats(uid);
471         DeleteUidSimStats(uid);
472         DeleteUidStatsFlag(uid);
473         DeleteUidSimSampleBundle(uid);
474         if (GetUidSimSampleBundlesSize() == 0) {
475             uidStatsFlagMap_.Clear();
476         }
477     };
478     return ffrt::submit_h(std::move(netCachedStats), {}, {}, ffrt::task_attr().name("NetForceArchiveStats"));
479 }
480 
Reset()481 void NetStatsCached::Reset() {}
482 
ForceCachedStats()483 void NetStatsCached::ForceCachedStats()
484 {
485     std::lock_guard<ffrt::mutex> lock(lock_);
486     CacheUidSimStats();
487     WriteUidSimStats();
488 }
489 
SetUidSimSampleBundle(uint32_t uid,const SampleBundleInfo & info)490 void NetStatsCached::SetUidSimSampleBundle(uint32_t uid, const SampleBundleInfo &info)
491 {
492     if (!info.Valid()) {
493         NETMGR_LOG_W("SetUidSimSampleBundle invalid. info[%{public}u, %{public}s]", uid, info.ToString().c_str());
494         return;
495     }
496     uidSimSampleBundleMap_.EnsureInsert(uid, info);
497 }
498 
DeleteUidSimSampleBundle(uint32_t uid)499 void NetStatsCached::DeleteUidSimSampleBundle(uint32_t uid)
500 {
501     uidSimSampleBundleMap_.Erase(uid);
502 }
503 
GetUidSimSampleBundle(uint32_t uid)504 std::optional<SampleBundleInfo> NetStatsCached::GetUidSimSampleBundle(uint32_t uid)
505 {
506     SampleBundleInfo info;
507     if (uidSimSampleBundleMap_.Find(uid, info)) {
508         return info;
509     }
510     return std::nullopt;
511 }
512 
GetUidSimSampleBundlesSize()513 uint32_t NetStatsCached::GetUidSimSampleBundlesSize()
514 {
515     return static_cast<uint32_t>(uidSimSampleBundleMap_.Size());
516 }
517 
SetUidStatsFlag(std::unordered_map<uint32_t,SampleBundleInfo> & sampleBundleMap)518 void NetStatsCached::SetUidStatsFlag(std::unordered_map<uint32_t, SampleBundleInfo> &sampleBundleMap)
519 {
520     if (sampleBundleMap.empty()) {
521         NETMGR_LOG_W("SetUidStatsFlag sampleBundleMap is empty");
522         return;
523     }
524     bool isExistSim = false;
525     bool isExistSim2 = false;
526     IsExistInUidSimSampleBundleMap(isExistSim, isExistSim2);
527     std::optional<SampleBundleInfo> earlySampleBundleOpt = GetEarlySampleBundleInfo();
528     for (auto iter = sampleBundleMap.begin(); iter != sampleBundleMap.end(); ++iter) {
529         if (!iter->second.Valid()) {
530             NETMGR_LOG_W("SetUidStatsFlag sampleBundleInfo is invalid. [%{public}s]", iter->second.ToString().c_str());
531             continue;
532         }
533         if (CommonUtils::IsSim(iter->second.bundleName_) || CommonUtils::IsSimAnco(iter->second.bundleName_)) {
534             uidStatsFlagMap_.EnsureInsert(iter->first, STATS_DATA_FLAG_SIM_BASIC);
535             continue;
536         } else if (CommonUtils::IsSim2(iter->second.bundleName_) || CommonUtils::IsSim2Anco(iter->second.bundleName_)) {
537             uidStatsFlagMap_.EnsureInsert(iter->first, STATS_DATA_FLAG_SIM2_BASIC);
538             continue;
539         }
540         if (CommonUtils::IsInstallSourceFromSim2(iter->second.installSource_)) {
541             uidStatsFlagMap_.EnsureInsert(iter->first,
542                                           isExistSim2 ? STATS_DATA_FLAG_SIM2 : STATS_DATA_FLAG_DEFAULT);
543         } else if (CommonUtils::IsInstallSourceFromSim(iter->second.installSource_)) {
544             uidStatsFlagMap_.EnsureInsert(iter->first, isExistSim ? STATS_DATA_FLAG_SIM : STATS_DATA_FLAG_DEFAULT);
545         } else if (iter->second.installSource_ == INSTALL_SOURCE_DEFAULT) {
546             if (!isExistSim && !isExistSim2) {
547                 uidStatsFlagMap_.EnsureInsert(iter->first, STATS_DATA_FLAG_DEFAULT);
548                 continue;
549             }
550             if (earlySampleBundleOpt.has_value() &&
551                 CommonUtils::IsSim2(earlySampleBundleOpt.value().bundleName_) && isExistSim2) {
552                 uidStatsFlagMap_.EnsureInsert(iter->first, STATS_DATA_FLAG_SIM2_BASIC);
553             } else if (isExistSim) {
554                 uidStatsFlagMap_.EnsureInsert(iter->first, STATS_DATA_FLAG_SIM_BASIC);
555             } else {
556                 uidStatsFlagMap_.EnsureInsert(iter->first, STATS_DATA_FLAG_DEFAULT);
557             }
558         }
559     }
560 }
561 
DeleteUidStatsFlag(uint32_t uid)562 void NetStatsCached::DeleteUidStatsFlag(uint32_t uid)
563 {
564     uidStatsFlagMap_.Erase(uid);
565 }
566 
ClearUidStatsFlag()567 void NetStatsCached::ClearUidStatsFlag()
568 {
569     ForceCachedStats();
570     uidStatsFlagMap_.Clear();
571 }
572 
GetUidStatsFlag(uint32_t uid)573 NetStatsDataFlag NetStatsCached::GetUidStatsFlag(uint32_t uid)
574 {
575     NetStatsDataFlag flag = STATS_DATA_FLAG_DEFAULT;
576     if (uidStatsFlagMap_.Find(uid, flag)) {
577         return flag;
578     }
579     if (uidSimSampleBundleMap_.Size() < 1) {
580         uidStatsFlagMap_.EnsureInsert(uid, flag);
581         return flag;
582     }
583     bool isExistSim = false;
584     uidSimSampleBundleMap_.Iterate([&isExistSim](const uint32_t &k, const SampleBundleInfo &v) {
585         if (CommonUtils::IsSim(v.bundleName_)) {
586             isExistSim = true;
587         }
588     });
589     flag = isExistSim ? STATS_DATA_FLAG_SIM_BASIC : STATS_DATA_FLAG_DEFAULT;
590     uidStatsFlagMap_.EnsureInsert(uid, flag);
591     return flag;
592 }
593 
GetEarlySampleBundleInfo()594 std::optional<SampleBundleInfo> NetStatsCached::GetEarlySampleBundleInfo()
595 {
596     std::map<uint32_t, SampleBundleInfo> tmp;
597     uidSimSampleBundleMap_.Iterate([&tmp](uint32_t uid, const SampleBundleInfo &info) { tmp.emplace(uid, info); });
598     auto earlySampleBundle = std::max_element(
599         tmp.begin(), tmp.end(), [](std::pair<uint32_t, SampleBundleInfo> l, std::pair<uint32_t, SampleBundleInfo> r) {
600             return l.second.installTime_ > r.second.installTime_;
601         });
602     if (earlySampleBundle != tmp.end()) {
603         return earlySampleBundle->second;
604     } else {
605         NETMGR_LOG_W("SetUidStatsFlag earlySampleBundle is not exist.");
606         return std::nullopt;
607     }
608 }
609 
IsExistInUidSimSampleBundleMap(bool & isExistSim,bool & isExistSim2)610 void NetStatsCached::IsExistInUidSimSampleBundleMap(bool &isExistSim, bool &isExistSim2)
611 {
612     isExistSim = false;
613     isExistSim2 = false;
614     uidSimSampleBundleMap_.Iterate([&isExistSim2, &isExistSim](uint32_t uid, const SampleBundleInfo &info) {
615         if (CommonUtils::IsSim(info.bundleName_)) {
616             isExistSim = true;
617         }
618         if (CommonUtils::IsSim2(info.bundleName_)) {
619             isExistSim2 = true;
620         }
621     });
622 }
623 
DeleteUidStats(uint32_t uid)624 void NetStatsCached::DeleteUidStats(uint32_t uid)
625 {
626     auto ret = NetsysController::GetInstance().DeleteStatsInfo(uid);
627     if (ret != NETMANAGER_SUCCESS) {
628         NETMGR_LOG_E("DeleteUidStats statsInfo failed. ret is %{public}d", ret);
629     }
630     std::lock_guard<ffrt::mutex> lock(lock_);
631     stats_.ResetUidStats(uid);
632     lastUidStatsInfo_.erase(std::remove_if(lastUidStatsInfo_.begin(), lastUidStatsInfo_.end(),
633                                            [uid](const auto &item) { return item.uid_ == uid; }),
634                             lastUidStatsInfo_.end());
635     uidPushStatsInfo_.erase(std::remove_if(uidPushStatsInfo_.begin(), uidPushStatsInfo_.end(),
636                                            [uid](const auto &item) { return item.uid_ == uid; }),
637                             uidPushStatsInfo_.end());
638 }
639 
DeleteUidSimStats(uint32_t uid)640 void NetStatsCached::DeleteUidSimStats(uint32_t uid)
641 {
642     std::optional<SampleBundleInfo> sampleBundleInfoOpt = GetUidSimSampleBundle(uid);
643     DeleteUidSimSampleBundle(uid);
644     if (!sampleBundleInfoOpt.has_value()) {
645         auto ret = NetsysController::GetInstance().DeleteSimStatsInfo(uid);
646         if (ret != NETMANAGER_SUCCESS) {
647             NETMGR_LOG_E("DeleteUidSimStats SimStatsInfo Failed. ret is %{public}d", ret);
648         }
649         std::lock_guard<ffrt::mutex> lock(lock_);
650         stats_.ResetUidSimStats(uid);
651         lastUidSimStatsInfo_.erase(std::remove_if(lastUidSimStatsInfo_.begin(), lastUidSimStatsInfo_.end(),
652                                                   [uid](const auto &item) { return item.uid_ == uid; }),
653                                    lastUidSimStatsInfo_.end());
654         return;
655     }
656     auto sampleBundleInfo = sampleBundleInfoOpt.value();
657     if (!sampleBundleInfo.Valid()) {
658         NETMGR_LOG_W("DeleteUidSimStats invalid info[%{public}s]", sampleBundleInfo.ToString().c_str());
659         return;
660     }
661     if (CommonUtils::IsSim(sampleBundleInfo.bundleName_) ||
662         CommonUtils::IsSim2(sampleBundleInfo.bundleName_)) {
663         auto flagBasic =
664             CommonUtils::IsSim(sampleBundleInfo.bundleName_) ? STATS_DATA_FLAG_SIM_BASIC : STATS_DATA_FLAG_SIM2_BASIC;
665         auto flagHap = (flagBasic == STATS_DATA_FLAG_SIM_BASIC) ? STATS_DATA_FLAG_SIM : STATS_DATA_FLAG_SIM2;
666         DeleteUidSimStatsWithFlag(uid, flagBasic);
667         DeleteUidSimStatsWithFlag(uid, flagHap);
668     }
669 }
670 
DeleteUidSimStatsWithFlag(uint32_t uid,uint32_t flag)671 void NetStatsCached::DeleteUidSimStatsWithFlag(uint32_t uid, uint32_t flag)
672 {
673     auto handler = std::make_unique<NetStatsDataHandler>();
674     if (handler == nullptr || handler->UpdateSimDataFlag(flag, STATS_DATA_FLAG_UNINSTALLED) != NETMANAGER_SUCCESS) {
675         NETMGR_LOG_E("DeleteUidSimStats updateFlag failed. uid:[%{public}d], flag[%{public}u]", uid, flag);
676     }
677     std::lock_guard<ffrt::mutex> lock(lock_);
678     lastUidSimStatsInfo_.erase(std::remove_if(lastUidSimStatsInfo_.begin(), lastUidSimStatsInfo_.end(),
679                                               [flag](const auto &item) { return item.flag_ == flag; }),
680                                lastUidSimStatsInfo_.end());
681     std::vector<uint32_t> uidList{uid};
682     uidStatsFlagMap_.Iterate([flag, &uidList](const uint32_t &k, const NetStatsDataFlag &v) {
683         if (flag == v) {
684             uidList.push_back(k);
685         }
686     });
687     std::for_each(uidList.begin(), uidList.end(), [this](const uint32_t uid) {
688         uidStatsFlagMap_.EnsureInsert(uid, STATS_DATA_FLAG_DEFAULT);
689         auto ret = NetsysController::GetInstance().DeleteSimStatsInfo(uid);
690         if (ret != NETMANAGER_SUCCESS) {
691             NETMGR_LOG_E("DeleteUidSimStats SimStatsInfo Failed. ret[%{public}d], uid[%{public}u]", ret, uid);
692         }
693     });
694 }
695 
696 #ifdef SUPPORT_NETWORK_SHARE
DeleteIptablesStats()697 void NetStatsCached::DeleteIptablesStats()
698 {
699     std::lock_guard<ffrt::mutex> lock(lock_);
700     stats_.ResetIptablesStats();
701     lastIptablesStatsInfo_.clear();
702 }
703 #endif
704 
GetKernelUidStats(std::vector<NetStatsInfo> & statsInfo)705 void NetStatsCached::GetKernelUidStats(std::vector<NetStatsInfo> &statsInfo)
706 {
707     std::vector<NetStatsInfo> allInfos;
708     NetsysController::GetInstance().GetAllStatsInfo(allInfos);
709     ifaceNameIdentMap_.Iterate([&allInfos](const std::string &k, const std::string &v) {
710         std::for_each(allInfos.begin(), allInfos.end(), [&k, &v](NetStatsInfo &item) {
711             if (item.iface_ == k) {
712                 item.ident_ = v;
713             }
714         });
715     });
716     std::for_each(allInfos.begin(), allInfos.end(), [this, &statsInfo](NetStatsInfo &info) {
717         if (info.iface_ == IFACE_LO) {
718             return;
719         }
720         NetStatsInfo tmp = GetIncreasedStats(info);
721         if (tmp.HasNoData()) {
722             return;
723         }
724         tmp.date_ = CommonUtils::GetCurrentSecond();
725         statsInfo.push_back(std::move(tmp));
726     });
727 }
728 
GetKernelUidSimStats(std::vector<NetStatsInfo> & statsInfo)729 void NetStatsCached::GetKernelUidSimStats(std::vector<NetStatsInfo> &statsInfo)
730 {
731     std::vector<NetStatsInfo> SimInfos;
732     NetsysController::GetInstance().GetAllSimStatsInfo(SimInfos);
733     ifaceNameIdentMap_.Iterate([&SimInfos](const std::string &k, const std::string &v) {
734         std::for_each(SimInfos.begin(), SimInfos.end(), [&k, &v](NetStatsInfo &item) {
735             if (item.iface_ == k) {
736                 item.ident_ = v;
737             }
738         });
739     });
740     uidStatsFlagMap_.Iterate([&SimInfos](const uint32_t &k, const NetStatsDataFlag &v) {
741         std::for_each(SimInfos.begin(), SimInfos.end(), [&k, &v](NetStatsInfo &item) {
742             if (item.uid_ == k) {
743                 item.flag_ = v;
744             }
745         });
746     });
747     std::for_each(SimInfos.begin(), SimInfos.end(), [this, &statsInfo](NetStatsInfo &info) {
748         if (info.iface_ == IFACE_LO) {
749             return;
750         }
751         NetStatsInfo tmp = GetIncreasedSimStats(info);
752         if (tmp.HasNoData()) {
753             return;
754         }
755         tmp.date_ = CommonUtils::GetCurrentSecond();
756         if (tmp.flag_ <= STATS_DATA_FLAG_DEFAULT || tmp.flag_ >= STATS_DATA_FLAG_LIMIT) {
757             tmp.flag_ = GetUidStatsFlag(tmp.uid_);
758         }
759         if (tmp.flag_ == STATS_DATA_FLAG_SIM_BASIC) {
760             tmp.uid_ = Sim_UID;
761         } else if (tmp.flag_ == STATS_DATA_FLAG_SIM2_BASIC) {
762             tmp.uid_ = SIM2_UID;
763         } else if (tmp.flag_ != STATS_DATA_FLAG_SIM && tmp.flag_ != STATS_DATA_FLAG_SIM2) {
764             return;
765         }
766         statsInfo.push_back(std::move(tmp));
767     });
768 }
769 
770 #ifdef SUPPORT_NETWORK_SHARE
GetIptablesStatsCached(std::vector<NetStatsInfo> & iptablesStatsInfo)771 void NetStatsCached::GetIptablesStatsCached(std::vector<NetStatsInfo> &iptablesStatsInfo)
772 {
773     std::lock_guard<ffrt::mutex> lock(lock_);
774     iptablesStatsInfo.insert(iptablesStatsInfo.end(),
775         stats_.GetIptablesStatsInfo().begin(), stats_.GetIptablesStatsInfo().end());
776     GetIptablesStatsIncrease(iptablesStatsInfo);
777 }
778 
CacheIptablesStats()779 void NetStatsCached::CacheIptablesStats()
780 {
781     std::string ifaceName;
782     nmd::NetworkSharingTraffic traffic;
783 
784     int32_t ret = NetsysController::GetInstance().GetNetworkCellularSharingTraffic(traffic, ifaceName);
785     if (ret != NETMANAGER_SUCCESS) {
786         NETMGR_LOG_E("GetTrafficBytes err, ret[%{public}d]", ret);
787         return;
788     }
789     CacheIptablesStatsService(traffic, ifaceName);
790 }
791 
CacheIptablesStatsService(nmd::NetworkSharingTraffic & traffic,std::string & ifaceName)792 void NetStatsCached::CacheIptablesStatsService(nmd::NetworkSharingTraffic &traffic, std::string &ifaceName)
793 {
794     NetStatsInfo statsInfos;
795     statsInfos.uid_ = IPTABLES_UID;
796     statsInfos.iface_ = ifaceName;
797     statsInfos.rxBytes_ = static_cast<uint64_t>(traffic.receive);
798     statsInfos.txBytes_ = static_cast<uint64_t>(traffic.send);
799     statsInfos.flag_ = STATS_DATA_FLAG_DEFAULT;
800     statsInfos.rxPackets_ = statsInfos.rxBytes_ > 0 ? 1 : 0;
801     statsInfos.txPackets_ = statsInfos.txBytes_ > 0 ? 1 : 0;
802     std::vector<NetStatsInfo> statsInfosVec;
803     statsInfosVec.push_back(std::move(statsInfos));
804 
805     ifaceNameIdentMap_.Iterate([&statsInfosVec](const std::string &k, const std::string &v) {
806         std::for_each(statsInfosVec.begin(), statsInfosVec.end(), [&k, &v](NetStatsInfo &item) {
807             if (item.iface_ == k) {
808                 item.ident_ = v;
809             }
810         });
811     });
812 
813     std::for_each(statsInfosVec.begin(), statsInfosVec.end(), [this](NetStatsInfo &info) {
814         if (info.iface_ == IFACE_LO) {
815             return;
816         }
817         auto findRet = std::find_if(lastIptablesStatsInfo_.begin(), lastIptablesStatsInfo_.end(),
818             [this, &info](const NetStatsInfo &lastInfo) {return info.Equals(lastInfo); });
819         if (findRet == lastIptablesStatsInfo_.end()) {
820             stats_.PushIptablesStats(info);
821             return;
822         }
823         auto currentStats = info - *findRet;
824         stats_.PushIptablesStats(currentStats);
825     });
826     NETMGR_LOG_D("CacheIptablesStatsService info success");
827     lastIptablesStatsInfo_.swap(statsInfosVec);
828 }
829 
GetIptablesStatsIncrease(std::vector<NetStatsInfo> & infosVec)830 void NetStatsCached::GetIptablesStatsIncrease(std::vector<NetStatsInfo> &infosVec)
831 {
832     std::string ifaceName;
833     nmd::NetworkSharingTraffic traffic;
834     int32_t ret = NetsysController::GetInstance().GetNetworkCellularSharingTraffic(traffic, ifaceName);
835     if (ret != NETMANAGER_SUCCESS) {
836         NETMGR_LOG_E("GetTrafficBytes err, ret[%{public}d]", ret);
837         return;
838     }
839     NetStatsInfo statsInfos;
840     statsInfos.uid_ = IPTABLES_UID;
841     statsInfos.iface_ = ifaceName;
842     statsInfos.rxBytes_ = static_cast<uint64_t>(traffic.receive);
843     statsInfos.txBytes_ = static_cast<uint64_t>(traffic.send);
844     statsInfos.flag_ = STATS_DATA_FLAG_DEFAULT;
845     statsInfos.rxPackets_ = statsInfos.rxBytes_ > 0 ? 1 : 0;
846     statsInfos.txPackets_ = statsInfos.txBytes_ > 0 ? 1 : 0;
847     statsInfos.date_ = CommonUtils::GetCurrentSecond();
848 
849     std::vector<NetStatsInfo> statsInfosVec;
850     statsInfosVec.push_back(std::move(statsInfos));
851 
852     ifaceNameIdentMap_.Iterate([&statsInfosVec](const std::string &k, const std::string &v) {
853         std::for_each(statsInfosVec.begin(), statsInfosVec.end(), [&k, &v](NetStatsInfo &item) {
854             if (item.iface_ == k) {
855                 item.ident_ = v;
856             }
857         });
858     });
859     std::vector<NetStatsInfo> tmpInfosVec;
860     if (!lastIptablesStatsInfo_.empty()) {
861         std::for_each(statsInfosVec.begin(), statsInfosVec.end(), [this, &tmpInfosVec](NetStatsInfo &info) {
862             if (info.iface_ == IFACE_LO) {
863                 return;
864             }
865             auto findRet = std::find_if(lastIptablesStatsInfo_.begin(), lastIptablesStatsInfo_.end(),
866                 [this, &info](const NetStatsInfo &lastInfo) {return info.Equals(lastInfo); });
867             if (findRet == lastIptablesStatsInfo_.end()) {
868                 tmpInfosVec.push_back(std::move(info));
869             } else {
870                 tmpInfosVec.push_back(info - *findRet);
871             }
872         });
873     } else {
874         tmpInfosVec = statsInfosVec;
875     }
876     infosVec.insert(infosVec.end(), tmpInfosVec.begin(), tmpInfosVec.end());
877 }
878 #endif
879 
SaveSharingTraffic(const NetStatsInfo & infos)880 void NetStatsCached::SaveSharingTraffic(const NetStatsInfo &infos)
881 {
882     NETMGR_LOG_I("SaveSharingTraffic enter");
883 #ifdef SUPPORT_NETWORK_SHARE
884     std::lock_guard<ffrt::mutex> lock(lock_);
885     if (infos.iface_ == "" || infos.iface_.find(CELLULAR_IFACE_NAME) == std::string::npos) {
886         NETMGR_LOG_D("ifaceName not cellular [%{public}s]", infos.iface_.c_str());
887         return;
888     }
889     nmd::NetworkSharingTraffic traffic;
890     traffic.receive = infos.rxBytes_;
891     traffic.send = infos.txBytes_;
892     std::string ifaceName = infos.iface_;
893     CacheIptablesStatsService(traffic, ifaceName);
894     WriteIptablesStats();
895     lastIptablesStatsInfo_.clear();
896 #endif
897 }
898 } // namespace NetManagerStandard
899 } // namespace OHOS
900