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