• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
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 #include "network_plugin.h"
16 
17 #include <string>
18 #include <sys/stat.h>
19 
20 #include "buffer_splitter.h"
21 #include "common.h"
22 #include "network_plugin_result.pbencoder.h"
23 #include "securec.h"
24 #include "application_info.h"
25 #include "bundle_mgr_proxy.h"
26 #include "file_ex.h"
27 #include "iservice_registry.h"
28 #include "system_ability_definition.h"
29 #include "os_account_info.h"
30 #include "os_account_manager.h"
31 #include "common.h"
32 
33 namespace {
34 using namespace OHOS::Developtools::Profiler;
35 using namespace OHOS;
36 using namespace OHOS::AppExecFwk;
37 constexpr size_t READ_BUFFER_SIZE = 1024 * 16;
38 const std::string DEFAULT_NET_PATH("/proc/net/xt_qtaguid/stats");
39 } // namespace
40 
NetworkPlugin()41 NetworkPlugin::NetworkPlugin() : fp_(nullptr, nullptr)
42 {
43     pidUid_.clear();
44     buffer_ = std::make_unique<uint8_t[]>(READ_BUFFER_SIZE);
45 }
46 
Start(const uint8_t * configData,uint32_t configSize)47 int NetworkPlugin::Start(const uint8_t* configData, uint32_t configSize)
48 {
49     CHECK_NOTNULL(buffer_, -1, "%s:NetworkPlugin, buffer_ is null", __func__);
50 
51     if (protoConfig_.ParseFromArray(configData, configSize) <= 0) {
52         PROFILER_LOG_ERROR(LOG_CORE, "%s:NetworkPlugin, parseFromArray failed!", __func__);
53         return -1;
54     }
55 
56     for (int i = 0; i < protoConfig_.pid().size(); i++) {
57         int32_t pid = protoConfig_.pid(i);
58         pidUid_.emplace(pid, GetUid(pid));
59     }
60     if (protoConfig_.pid().empty() && protoConfig_.test_file() == "") {
61         PROFILER_LOG_INFO(LOG_CORE, "NetworkPlugin New Version!");
62         isNewVersion = true;
63         singlePid_ = protoConfig_.single_pid();
64         CHECK_TRUE(singlePid_ >= 0, -1, "%s:invalid pid", __func__);
65         if (protoConfig_.startup_process_name() != "") {
66             bundleName_ = protoConfig_.startup_process_name();
67             singleUid_ = GetUidByConfiguredBundleName(bundleName_);
68             CHECK_TRUE(singleUid_ != -1, -1, "%s:get uid failed", __func__);
69         } else if (protoConfig_.restart_process_name() != "") {
70             bundleName_ = protoConfig_.restart_process_name();
71             singleUid_ = GetUidByConfiguredBundleName(bundleName_);
72             CHECK_TRUE(singleUid_ != -1, -1, "%s:get uid failed", __func__);
73         } else if (singlePid_ > 0) {
74             std::string name = GetBundleNameByPid(singlePid_);
75             CHECK_TRUE(name != "", -1, "%s:get bundle name failed", __func__);
76             bundleName_ = name;
77             singleUid_ = GetUidByConfiguredBundleName(name);
78             CHECK_TRUE(singleUid_ != -1, -1, "%s:get uid failed", __func__);
79         }
80     }
81 
82     int ret = COMMON::PluginWriteToHisysevent("network_plugin", "sh", GetCmdArgs(protoConfig_),
83                                               COMMON::ErrorType::RET_SUCC, "success");
84     PROFILER_LOG_INFO(LOG_CORE, "%s: NetworkPlugin success! hisysevent report result:%d", __func__, ret);
85     return 0;
86 }
87 
GetCmdArgs(const NetworkConfig & traceConfig)88 std::string NetworkPlugin::GetCmdArgs(const NetworkConfig& traceConfig)
89 {
90     std::stringstream args;
91     for (const auto& p : traceConfig.pid()) {
92         args << "pid: " << COMMON::GetProcessNameByPid(p) << ", ";
93     }
94     args << "test_file: " << traceConfig.test_file();
95     return args.str();
96 }
97 
WriteNetWorkData(T & networkDatasProto)98 template <typename T> bool NetworkPlugin::WriteNetWorkData(T& networkDatasProto)
99 {
100     std::string file = GetRateNodePath();
101     if (protoConfig_.test_file() != "") {
102         file = protoConfig_.test_file();
103     }
104 
105     struct stat s;
106     lstat(file.c_str(), &s);
107     CHECK_TRUE(!S_ISDIR(s.st_mode), false, "%s:path(%s) is directory, no data to report", __func__, file.c_str());
108 
109     char realPath[PATH_MAX + 1] = {0};
110     CHECK_TRUE((file.length() < PATH_MAX) && (realpath(file.c_str(), realPath) != nullptr), false,
111                "%s:path is invalid: %s, errno=%d", __func__, file.c_str(), errno);
112     fp_ = std::unique_ptr<FILE, int (*)(FILE*)>(fopen(realPath, "r"), fclose);
113     CHECK_NOTNULL(fp_, false, "%s:NetworkPlugin, open(%s) Failed, errno(%d)", __func__, file.c_str(), errno);
114 
115     if (protoConfig_.pid().size() > 0) {
116         for (int i = 0; i < protoConfig_.pid().size(); i++) {
117             auto* info = networkDatasProto.add_networkinfo();
118             int32_t pid = protoConfig_.pid(i);
119             NetworkCell dataCell = {0};
120             ReadTxRxBytes(pid, dataCell);
121             // set proto
122             for (auto& it : dataCell.details) {
123                 auto* data = info->add_details();
124                 data->set_tx_bytes(it.tx);
125                 data->set_rx_bytes(it.rx);
126                 data->set_type(it.type);
127             }
128             info->set_pid(pid);
129             info->set_tx_bytes(dataCell.tx);
130             info->set_rx_bytes(dataCell.rx);
131             info->set_tv_sec(dataCell.ts.tv_sec);
132             info->set_tv_nsec(dataCell.ts.tv_nsec);
133         }
134     } else if (protoConfig_.test_file() != "") { // test data
135         NetSystemData systemData = {};
136         ReadSystemTxRxBytes(systemData);
137         static int randNum = 0;
138         randNum++;
139         auto* systemInfo = networkDatasProto.mutable_network_system_info();
140         for (auto& it : systemData.details) {
141             auto* data = systemInfo->add_details();
142             data->set_rx_bytes(it.rxBytes + randNum * RX_BYTES_INDEX);
143             data->set_rx_packets(it.rxPackets + randNum * RX_PACKETS_INDEX);
144             data->set_tx_bytes(it.txBytes + randNum * TX_BYTES_INDEX);
145             data->set_tx_packets(it.txPackets + randNum * TX_PACKETS_INDEX);
146             data->set_type(it.type);
147         }
148         systemInfo->set_tv_sec(systemData.ts.tv_sec);
149         systemInfo->set_tv_nsec(systemData.ts.tv_nsec);
150         systemInfo->set_rx_bytes(systemData.rxBytes + (randNum * RX_BYTES_INDEX * systemData.details.size()));
151         systemInfo->set_rx_packets(systemData.rxPackets + (randNum * RX_PACKETS_INDEX * systemData.details.size()));
152         systemInfo->set_tx_bytes(systemData.txBytes + (randNum * TX_BYTES_INDEX * systemData.details.size()));
153         systemInfo->set_tx_packets(systemData.txPackets + (randNum * TX_PACKETS_INDEX * systemData.details.size()));
154     } else { // real data
155         NetSystemData systemData = {};
156         ReadSystemTxRxBytes(systemData);
157         auto* systemInfo = networkDatasProto.mutable_network_system_info();
158         for (auto& it : systemData.details) {
159             auto* data = systemInfo->add_details();
160             data->set_rx_bytes(it.rxBytes);
161             data->set_rx_packets(it.rxPackets);
162             data->set_tx_bytes(it.txBytes);
163             data->set_tx_packets(it.txPackets);
164             data->set_type(it.type);
165         }
166         systemInfo->set_tv_sec(systemData.ts.tv_sec);
167         systemInfo->set_tv_nsec(systemData.ts.tv_nsec);
168         systemInfo->set_rx_bytes(systemData.rxBytes);
169         systemInfo->set_rx_packets(systemData.rxPackets);
170         systemInfo->set_tx_bytes(systemData.txBytes);
171         systemInfo->set_tx_packets(systemData.txPackets);
172     }
173 
174     return true;
175 }
176 
ReportOptimize(RandomWriteCtx * randomWrite)177 int NetworkPlugin::ReportOptimize(RandomWriteCtx* randomWrite)
178 {
179     if (isNewVersion) {
180         ProtoEncoder::NetworkFlowData dataProto(randomWrite);
181         CHECK_TRUE(WriteNetFlowData(dataProto), -1, "%s:write network data failed", __func__);
182 
183         int msgSize = dataProto.Finish();
184         return msgSize;
185     } else {
186         ProtoEncoder::NetworkDatas dataProto(randomWrite);
187         CHECK_TRUE(WriteNetWorkData(dataProto), -1, "%s:write network data failed", __func__);
188 
189         int msgSize = dataProto.Finish();
190         return msgSize;
191     }
192 }
193 
Report(uint8_t * data,uint32_t dataSize)194 int NetworkPlugin::Report(uint8_t* data, uint32_t dataSize)
195 {
196     if (isNewVersion) {
197         NetworkFlowData dataProto;
198         CHECK_TRUE(WriteNetFlowData(dataProto), -1, "%s:write network data failed", __func__);
199 
200         uint32_t length = dataProto.ByteSizeLong();
201         if (length > dataSize) {
202             return -length;
203         }
204         if (dataProto.SerializeToArray(data, length) > 0) {
205             return length;
206         }
207         return 0;
208     } else {
209         NetworkDatas dataProto;
210         CHECK_TRUE(WriteNetWorkData(dataProto), -1, "%s:write network data failed", __func__);
211 
212         uint32_t length = dataProto.ByteSizeLong();
213         if (length > dataSize) {
214             return -length;
215         }
216         if (dataProto.SerializeToArray(data, length) > 0) {
217             return length;
218         }
219         return 0;
220     }
221 }
222 
Stop()223 int NetworkPlugin::Stop()
224 {
225     buffer_ = nullptr;
226     fp_ = nullptr;
227     pidUid_.clear();
228 
229     PROFILER_LOG_INFO(LOG_CORE, "%s:NetworkPlugin, stop success!", __func__);
230     return 0;
231 }
232 
GetRateNodePath()233 std::string NetworkPlugin::GetRateNodePath()
234 {
235     std::string name = "";
236 
237     if (!fileForTest_.empty()) {
238         name = fileForTest_ + DEFAULT_NET_PATH;
239         return name;
240     }
241     if (access(DEFAULT_NET_PATH.c_str(), F_OK) == 0) {
242         name = DEFAULT_NET_PATH;
243     }
244     return name;
245 }
246 
GetUid(int32_t pid)247 int32_t NetworkPlugin::GetUid(int32_t pid)
248 {
249     CHECK_TRUE(pid > 0, -1, "%s:NetworkPlugin, check param fail, pid less than 0!", __func__);
250 
251     char* end = nullptr;
252     std::string path = std::string("/proc/") + std::to_string(pid) + std::string("/status");
253     if (!fileForTest_.empty()) {
254         path = fileForTest_ + std::string("/proc/") + std::to_string(pid) + std::string("/status");
255     }
256     std::ifstream input(path, std::ios::in);
257     if (input.fail()) {
258         const int bufSize = 256;
259         char buf[bufSize] = { 0 };
260         strerror_r(errno, buf, bufSize);
261         PROFILER_LOG_ERROR(LOG_CORE, "%s:NetworkPlugin, open %s failed, errno(%s)", __func__, path.c_str(), buf);
262         return -1;
263     }
264     do {
265         if (!input.good()) {
266             return -1;
267         }
268         std::string line;
269         getline(input, line);
270         if (!strncmp(line.c_str(), "Uid:", strlen("Uid:"))) {
271             std::string str = line.substr(strlen("Uid:\t"));
272             PROFILER_LOG_INFO(LOG_CORE, "%s:NetworkPlugin, line(%s), str(%s)", __func__, line.c_str(), str.c_str());
273             return strtol(str.c_str(), &end, DEC_BASE);
274         }
275     } while (!input.eof());
276     input.close();
277 
278     return -1;
279 }
280 
ReadTxRxBytes(int32_t pid,NetworkCell & cell)281 bool NetworkPlugin::ReadTxRxBytes(int32_t pid, NetworkCell &cell)
282 {
283     int32_t uid = pidUid_.at(pid);
284     CHECK_NOTNULL(fp_.get(), false, "%s:NetworkPlugin, fp_ is null", __func__);
285     int ret = fseek(fp_.get(), 0, SEEK_SET);
286     CHECK_TRUE(ret == 0, false, "%s:NetworkPlugin, fseek failed, error(%d)!", __func__, errno);
287     size_t rsize = static_cast<size_t>(fread(buffer_.get(), sizeof(char), READ_BUFFER_SIZE - 1, fp_.get()));
288     buffer_.get()[rsize] = '\0';
289     CHECK_TRUE(rsize >= 0, false, "%s:NetworkPlugin, read failed, errno(%d)", __func__, errno);
290     char* end = nullptr;
291     BufferSplitter totalbuffer((const char*)buffer_.get(), rsize + 1);
292     do {
293         int index = 0;
294         NetDetails cache = {0};
295         char tmp[TX_BYTES_INDEX + 1] = {0};
296         while (totalbuffer.NextWord(' ')) {
297             index++;
298             if (totalbuffer.CurWord() == nullptr) {
299                 continue;
300             }
301             if (index == IFACE_INDEX && !strncmp(totalbuffer.CurWord(), "lo", strlen("lo"))) {
302                 break;
303             }
304             if (index == IFACE_INDEX &&
305                 strncpy_s(tmp, sizeof(tmp), totalbuffer.CurWord(), totalbuffer.CurWordSize()) == EOK) {
306                 cache.type = tmp;
307             }
308             uint64_t value = static_cast<uint64_t>(strtoull(totalbuffer.CurWord(), &end, DEC_BASE));
309             CHECK_TRUE(value >= 0, false, "%s:NetworkPlugin, strtoull value failed", __func__);
310             if ((index == UID_INDEX) && (uid != static_cast<int32_t>(value))) {
311                 break;
312             }
313             if (index == RX_BYTES_INDEX) {
314                 uint64_t rxBytes = value;
315                 cache.rx = rxBytes;
316                 cell.rx += rxBytes;
317             }
318             if (index == TX_BYTES_INDEX) {
319                 uint64_t txBytes = value;
320                 cache.tx = txBytes;
321                 cell.tx += txBytes;
322                 AddNetDetails(cell, cache);
323             }
324         }
325     } while (totalbuffer.NextLine());
326 
327     clock_gettime(CLOCK_REALTIME, &cell.ts);
328 
329     return true;
330 }
331 
AddNetDetails(NetworkCell & cell,NetDetails & data)332 void NetworkPlugin::AddNetDetails(NetworkCell& cell, NetDetails& data)
333 {
334     bool finded = false;
335 
336     // 处理重复数据
337     for (auto it = cell.details.begin(); it != cell.details.end(); it++) {
338         if (it->type == data.type) {
339             it->tx += data.tx;
340             it->rx += data.rx;
341             finded = true;
342         }
343     }
344 
345     if (!finded) {
346         cell.details.push_back(data);
347     }
348 }
349 
ReadSystemTxRxBytes(NetSystemData & systemData)350 bool NetworkPlugin::ReadSystemTxRxBytes(NetSystemData &systemData)
351 {
352     CHECK_NOTNULL(fp_.get(), false, "%s:NetworkPlugin, fp_ is null", __func__);
353     int ret = fseek(fp_.get(), 0, SEEK_SET);
354     CHECK_TRUE(ret == 0, false, "%s:NetworkPlugin, fseek failed, error(%d)!", __func__, errno);
355     size_t rsize = static_cast<size_t>(fread(buffer_.get(), sizeof(char), READ_BUFFER_SIZE - 1, fp_.get()));
356     buffer_.get()[rsize] = '\0';
357     CHECK_TRUE(rsize >= 0, false, "%s:NetworkPlugin, read failed, errno(%d)", __func__, errno);
358     char* end = nullptr;
359     BufferSplitter totalbuffer((const char*)buffer_.get(), rsize + 1);
360     do {
361         int index = 0;
362         NetSystemDetails systemCache = {};
363         char tmp[TX_BYTES_INDEX + 1] = "";
364         while (totalbuffer.NextWord(' ')) {
365             index++;
366             if (totalbuffer.CurWord() == nullptr) {
367                 continue;
368             }
369             if (index == IFACE_INDEX && !strncmp(totalbuffer.CurWord(), "lo", strlen("lo"))) {
370                 break;
371             }
372             if (index == IFACE_INDEX &&
373                 strncpy_s(tmp, sizeof(tmp), totalbuffer.CurWord(), totalbuffer.CurWordSize()) == EOK) {
374                 systemCache.type = tmp;
375             }
376             if (strcmp(systemCache.type.c_str(), "iface") == 0) {
377                 break;
378             }
379             uint64_t value = static_cast<uint64_t>(strtoull(totalbuffer.CurWord(), &end, DEC_BASE));
380             CHECK_TRUE(value >= 0, false, "%s:NetworkPlugin, strtoull value failed", __func__);
381             if (index == RX_BYTES_INDEX) {
382                 uint64_t rxBytes = value;
383                 systemCache.rxBytes = rxBytes;
384                 systemData.rxBytes += rxBytes;
385             } else if (index == RX_PACKETS_INDEX) {
386                 uint64_t rxPackets = value;
387                 systemCache.rxPackets = rxPackets;
388                 systemData.rxPackets += rxPackets;
389             } else if (index == TX_BYTES_INDEX) {
390                 uint64_t txBytes = value;
391                 systemCache.txBytes = txBytes;
392                 systemData.txBytes += txBytes;
393             } else if (index == TX_PACKETS_INDEX) {
394                 uint64_t txPackets = value;
395                 systemCache.txPackets = txPackets;
396                 systemData.txPackets += txPackets;
397                 AddNetSystemDetails(systemData, systemCache);
398             }
399         }
400     } while (totalbuffer.NextLine());
401 
402     clock_gettime(CLOCK_REALTIME, &systemData.ts);
403 
404     return true;
405 }
406 
AddNetSystemDetails(NetSystemData & systemData,NetSystemDetails & data)407 void NetworkPlugin::AddNetSystemDetails(NetSystemData& systemData, NetSystemDetails& data)
408 {
409     bool finded = false;
410 
411     // 处理重复数据
412     for (auto it = systemData.details.begin(); it != systemData.details.end(); it++) {
413         if (it->type == data.type) {
414             it->rxBytes += data.rxBytes;
415             it->rxPackets += data.rxPackets;
416             it->txBytes += data.txBytes;
417             it->txPackets += data.txPackets;
418             finded = true;
419         }
420     }
421 
422     if (!finded) {
423         systemData.details.push_back(data);
424     }
425 }
426 
WriteNetFlowData(T & networkDatasProto)427 template <typename T> bool NetworkPlugin::WriteNetFlowData(T& networkDatasProto)
428 {
429     std::vector<OHOS::NetManagerStandard::NetStatsInfo> infos;
430     if (OHOS::NetManagerStandard::NetStatsClient::GetInstance().GetAllStatsInfo(infos) != 0) {
431         PROFILER_LOG_ERROR(LOG_CORE, "GetAllStatsInfo failed");
432         return false;
433     }
434     NetFlowData netFlowData = {{0, 0}, 0, 0, 0, 0, std::vector<NetFlowDetail>()};
435     if (bundleName_ != "") {
436         ScreenNetworkStatByUid(infos, netFlowData);
437     } else {
438         RetainAllNetworkStat(infos, netFlowData);
439     }
440     WriteData(networkDatasProto, netFlowData);
441     return true;
442 }
443 
WriteData(T & networkDatasProto,NetFlowData & netFlowData)444 template <typename T> void NetworkPlugin::WriteData(T &networkDatasProto, NetFlowData &netFlowData)
445 {
446     networkDatasProto.set_pid(singlePid_);
447     networkDatasProto.set_tv_sec(netFlowData.ts.tv_sec);
448     networkDatasProto.set_tv_nsec(netFlowData.ts.tv_nsec);
449     networkDatasProto.set_rx_bytes(netFlowData.rxBytes);
450     networkDatasProto.set_rx_packets(netFlowData.rxPackets);
451     networkDatasProto.set_tx_bytes(netFlowData.txBytes);
452     networkDatasProto.set_tx_packets(netFlowData.txPackets);
453     for (auto& it:netFlowData.details) {
454         auto* data = networkDatasProto.add_details();
455         data->set_type(it.type);
456         data->set_rx_bytes(it.rxBytes);
457         data->set_rx_packets(it.rxPackets);
458         data->set_tx_bytes(it.txBytes);
459         data->set_tx_packets(it.txPackets);
460     }
461 }
462 
RetainAllNetworkStat(const std::vector<OHOS::NetManagerStandard::NetStatsInfo> infos,NetFlowData & data)463 bool NetworkPlugin::RetainAllNetworkStat(const std::vector<OHOS::NetManagerStandard::NetStatsInfo> infos,
464                                          NetFlowData &data)
465 {
466     NetFlowData present = {{0, 0}, 0, 0, 0, 0, std::vector<NetFlowDetail>()};
467     std::map<std::string, NetFlowDetail> detailMap;
468     for (auto& info : infos) {
469         present.rxBytes += info.rxBytes_;
470         present.rxPackets += info.rxPackets_;
471         present.txBytes += info.txBytes_;
472         present.txPackets += info.txPackets_;
473         std::string type = info.iface_;
474         if (detailMap.find(type) != detailMap.end()) {
475             detailMap[type].rxBytes += info.rxBytes_;
476             detailMap[type].rxPackets += info.rxPackets_;
477             detailMap[type].txBytes += info.txBytes_;
478             detailMap[type].txPackets += info.txPackets_;
479         } else {
480             NetFlowDetail detail;
481             detail.type = info.iface_;
482             detail.rxBytes = info.rxBytes_;
483             detail.rxPackets = info.rxPackets_;
484             detail.txBytes = info.txBytes_;
485             detail.txPackets = info.txPackets_;
486             detailMap[type] = detail;
487         }
488     }
489     for (auto it : detailMap) {
490         present.details.push_back(it.second);
491     }
492     HandleData(present, data);
493     return true;
494 }
495 
ScreenNetworkStatByUid(const std::vector<OHOS::NetManagerStandard::NetStatsInfo> infos,NetFlowData & data)496 bool NetworkPlugin::ScreenNetworkStatByUid(const std::vector<OHOS::NetManagerStandard::NetStatsInfo> infos,
497                                            NetFlowData &data)
498 {
499     NetFlowData present = {{0, 0}, 0, 0, 0, 0, std::vector<NetFlowDetail>()};
500     for (auto& info : infos) {
501         if (static_cast<int32_t>(info.uid_) == singleUid_) {
502             NetFlowDetail detail;
503             detail.type = info.iface_;
504             detail.rxBytes = info.rxBytes_;
505             detail.rxPackets = info.rxPackets_;
506             detail.txBytes = info.txBytes_;
507             detail.txPackets = info.txPackets_;
508             present.details.push_back(detail);
509             present.rxBytes += info.rxBytes_;
510             present.rxPackets += info.rxPackets_;
511             present.txBytes += info.txBytes_;
512             present.txPackets += info.txPackets_;
513         }
514     }
515     HandleData(present, data);
516     return true;
517 }
518 
HandleData(NetFlowData present,NetFlowData & difference)519 bool NetworkPlugin::HandleData(NetFlowData present, NetFlowData &difference)
520 {
521     if (isFirst) {
522         (void)clock_gettime(CLOCK_REALTIME, &(difference.ts));
523         difference.rxBytes = 0;
524         difference.rxPackets = 0;
525         difference.txBytes = 0;
526         difference.txPackets = 0;
527         isFirst = false;
528         Record(present);
529         return true;
530     }
531 
532     (void)clock_gettime(CLOCK_REALTIME, &(difference.ts));
533     difference.rxBytes = present.rxBytes - previous_.rxBytes;
534     difference.rxPackets = present.rxPackets - previous_.rxPackets;
535     difference.txBytes = present.txBytes - previous_.txBytes;
536     difference.txPackets = present.txPackets - previous_.txPackets;
537     for (auto& presentDetail : present.details) {
538         NetFlowDetail detail;
539         bool havePrevious = false;
540         for (auto& previousDetail : previous_.details) {
541             if (previousDetail.type == presentDetail.type) {
542                 detail.type = presentDetail.type;
543                 detail.rxBytes = presentDetail.rxBytes - previousDetail.rxBytes;
544                 detail.rxPackets = presentDetail.rxPackets - previousDetail.rxPackets;
545                 detail.txBytes = presentDetail.txBytes - previousDetail.txBytes;
546                 detail.txPackets = presentDetail.txPackets - previousDetail.txPackets;
547                 havePrevious = true;
548                 break;
549             }
550         }
551         if (!havePrevious) {
552             detail.type = presentDetail.type;
553             detail.rxBytes = presentDetail.rxBytes;
554             detail.rxPackets = presentDetail.rxPackets;
555             detail.txBytes = presentDetail.txBytes;
556             detail.txPackets = presentDetail.txPackets;
557         }
558         difference.details.push_back(detail);
559     }
560     Record(present);
561     return true;
562 }
563 
Record(NetFlowData & newData)564 void NetworkPlugin::Record(NetFlowData &newData)
565 {
566     previous_.rxBytes = newData.rxBytes;
567     previous_.rxPackets = newData.rxPackets;
568     previous_.txBytes = newData.txBytes;
569     previous_.txPackets = newData.txPackets;
570     previous_.details.clear();
571     for (auto detail : newData.details) {
572         previous_.details.push_back(detail);
573     }
574 }
575 
GetBundleNameByPid(int32_t pid)576 std::string NetworkPlugin::GetBundleNameByPid(int32_t pid)
577 {
578     std::string bundleName;
579     std::string filePath = "/proc/" + std::to_string(pid) + "/cmdline";
580     LoadStringFromFile(filePath, bundleName);
581     bundleName.resize(strlen(bundleName.c_str()));
582     return bundleName;
583 }
584 
GetUidByConfiguredBundleName(std::string bundleName)585 int32_t NetworkPlugin::GetUidByConfiguredBundleName(std::string bundleName)
586 {
587     int32_t userId = 0;
588     std::vector<int32_t> activeIds;
589     if (AccountSA::OsAccountManager::QueryActiveOsAccountIds(activeIds) != 0) {
590         PROFILER_LOG_ERROR(LOG_CORE, "QueryActiveOsAccountIds failed");
591         return -1;
592     }
593     if (activeIds.empty()) {
594         PROFILER_LOG_ERROR(LOG_CORE, "active id is empty");
595         return -1;
596     }
597     userId = activeIds[0];
598     auto manager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
599     if (manager == nullptr) {
600         PROFILER_LOG_ERROR(LOG_CORE, "SystemAbilityManager is nullptr");
601         return -1;
602     }
603     sptr<IRemoteObject> remoteObject = manager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
604     if (remoteObject == nullptr) {
605         PROFILER_LOG_ERROR(LOG_CORE, "SystemAbility is nullptr");
606         return -1;
607     }
608     sptr<AppExecFwk::IBundleMgr> mgr = iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
609     if (mgr == nullptr) {
610         PROFILER_LOG_ERROR(LOG_CORE, "mgr is nullptr");
611         return -1;
612     }
613     int32_t uid = mgr->GetUidByBundleName(bundleName, userId);
614     return uid;
615 }