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 }