Refactor tetherGetStats by using stable aidl structure
Use stable aidl structure instead of persistbundle
Test: built, flashed, booted
system/netd/tests/runtests.sh passes
Change-Id: Id48cea4da4f9f4406ceb3d2281a5cfaaea8ce24f
diff --git a/server/Android.bp b/server/Android.bp
index 75e7d20..75667e9 100644
--- a/server/Android.bp
+++ b/server/Android.bp
@@ -24,12 +24,22 @@
],
}
+aidl_interface {
+ name: "netd_aidl_interface",
+ local_include_dir: "binder",
+ srcs: [
+ "binder/android/net/TetherStatsParcel.aidl",
+ ],
+ api_dir: "binder/api",
+}
+
cc_library {
name: "libnetdaidl",
defaults: ["netd_defaults"],
shared_libs: [
"libbinder",
"libutils",
+ "netd_aidl_interface-cpp",
],
aidl: {
export_aidl_headers: true,
@@ -86,6 +96,7 @@
"libpcap",
"libqtaguid",
"libssl",
+ "netd_aidl_interface-cpp",
],
aidl: {
export_aidl_headers: true,
@@ -125,6 +136,7 @@
"libssl",
"libsysutils",
"libutils",
+ "netd_aidl_interface-cpp",
],
static_libs: [
"libnetd_server",
@@ -209,5 +221,6 @@
"libqtaguid",
"libsysutils",
"libutils",
+ "netd_aidl_interface-cpp",
],
}
diff --git a/server/NetdNativeService.cpp b/server/NetdNativeService.cpp
index f2441f7..ff24ccd 100644
--- a/server/NetdNativeService.cpp
+++ b/server/NetdNativeService.cpp
@@ -16,6 +16,7 @@
#define LOG_TAG "Netd"
+#include <cinttypes>
#include <set>
#include <tuple>
#include <vector>
@@ -45,7 +46,7 @@
#include "UidRanges.h"
using android::base::StringPrintf;
-using android::os::PersistableBundle;
+using android::net::TetherStatsParcel;
namespace android {
namespace net {
@@ -489,37 +490,68 @@
namespace {
-void tetherAddStats(PersistableBundle *bundle, const TetherController::TetherStats& stats) {
- String16 iface = String16(stats.extIface.c_str());
- std::vector<int64_t> statsVector(INetd::TETHER_STATS_ARRAY_SIZE);
-
- bundle->getLongVector(iface, &statsVector);
- if (statsVector.size() == 0) {
- for (int i = 0; i < INetd::TETHER_STATS_ARRAY_SIZE; i++) statsVector.push_back(0);
+void tetherAddStatsByInterface(TetherController::TetherStats* tetherStatsParcel,
+ const TetherController::TetherStats& tetherStats) {
+ if (tetherStatsParcel->extIface == tetherStats.extIface) {
+ tetherStatsParcel->rxBytes += tetherStats.rxBytes;
+ tetherStatsParcel->rxPackets += tetherStats.rxPackets;
+ tetherStatsParcel->txBytes += tetherStats.txBytes;
+ tetherStatsParcel->txPackets += tetherStats.txPackets;
}
+}
- statsVector[INetd::TETHER_STATS_RX_BYTES] += stats.rxBytes;
- statsVector[INetd::TETHER_STATS_RX_PACKETS] += stats.rxPackets;
- statsVector[INetd::TETHER_STATS_TX_BYTES] += stats.txBytes;
- statsVector[INetd::TETHER_STATS_TX_PACKETS] += stats.txPackets;
+TetherStatsParcel toTetherStatsParcel(const TetherController::TetherStats& stats) {
+ TetherStatsParcel result;
+ result.iface = stats.extIface;
+ result.rxBytes = stats.rxBytes;
+ result.rxPackets = stats.rxPackets;
+ result.txBytes = stats.txBytes;
+ result.txPackets = stats.txPackets;
+ return result;
+}
- bundle->putLongVector(iface, statsVector);
+void setTetherStatsParcelVecByInterface(std::vector<TetherStatsParcel>* tetherStatsVec,
+ const TetherController::TetherStatsList& statsList) {
+ std::map<std::string, TetherController::TetherStats> statsMap;
+ for (const auto& stats : statsList) {
+ auto iter = statsMap.find(stats.extIface);
+ if (iter != statsMap.end()) {
+ tetherAddStatsByInterface(&(iter->second), stats);
+ } else {
+ statsMap.insert(
+ std::pair<std::string, TetherController::TetherStats>(stats.extIface, stats));
+ }
+ }
+ for (auto iter = statsMap.begin(); iter != statsMap.end(); iter++) {
+ tetherStatsVec->push_back(toTetherStatsParcel(iter->second));
+ }
+}
+
+std::vector<std::string> tetherStatsParcelVecToStringVec(std::vector<TetherStatsParcel>* tVec) {
+ std::vector<std::string> result;
+ for (const auto& t : *tVec) {
+ result.push_back(StringPrintf("%s:%" PRId64 ",%" PRId64 ",%" PRId64 ",%" PRId64,
+ t.iface.c_str(), t.rxBytes, t.rxPackets, t.txBytes,
+ t.txPackets));
+ }
+ return result;
}
} // namespace
-binder::Status NetdNativeService::tetherGetStats(PersistableBundle *bundle) {
+binder::Status NetdNativeService::tetherGetStats(
+ std::vector<TetherStatsParcel>* tetherStatsParcelVec) {
NETD_LOCKING_RPC(NETWORK_STACK, gCtls->tetherCtrl.lock);
+ auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__);
+
const auto& statsList = gCtls->tetherCtrl.getTetherStats();
if (!isOk(statsList)) {
return asBinderStatus(statsList);
}
-
- for (const auto& stats : statsList.value()) {
- tetherAddStats(bundle, stats);
- }
-
+ setTetherStatsParcelVecByInterface(tetherStatsParcelVec, statsList.value());
+ auto statsResults = tetherStatsParcelVecToStringVec(tetherStatsParcelVec);
+ gLog.log(entry.returns(base::Join(statsResults, ";")).withAutomaticDuration());
return binder::Status::ok();
}
diff --git a/server/NetdNativeService.h b/server/NetdNativeService.h
index 89c04f7..4da1335 100644
--- a/server/NetdNativeService.h
+++ b/server/NetdNativeService.h
@@ -94,7 +94,8 @@
// Tethering-related commands.
binder::Status tetherApplyDnsInterfaces(bool *ret) override;
- binder::Status tetherGetStats(android::os::PersistableBundle *ret) override;
+ binder::Status tetherGetStats(
+ std::vector<android::net::TetherStatsParcel>* tetherStatsVec) override;
binder::Status tetherStart(const std::vector<std::string>& dhcpRanges) override;
binder::Status tetherStop() override;
binder::Status tetherIsEnabled(bool* enabled) override;
diff --git a/server/binder/android/net/INetd.aidl b/server/binder/android/net/INetd.aidl
index 5f429c6..8147afa 100644
--- a/server/binder/android/net/INetd.aidl
+++ b/server/binder/android/net/INetd.aidl
@@ -17,7 +17,7 @@
package android.net;
import android.net.UidRange;
-import android.os.PersistableBundle;
+import android.net.TetherStatsParcel;
/** {@hide} */
interface INetd {
@@ -254,24 +254,16 @@
*/
boolean tetherApplyDnsInterfaces();
- // Ordering of the elements in the arrays returned by tetherGetStats.
- const int TETHER_STATS_RX_BYTES = 0;
- const int TETHER_STATS_RX_PACKETS = 1;
- const int TETHER_STATS_TX_BYTES = 2;
- const int TETHER_STATS_TX_PACKETS = 3;
- const int TETHER_STATS_ARRAY_SIZE = 4;
-
/**
* Return tethering statistics.
*
- * @return a PersistableBundle, where each entry maps the upstream interface name to an array
- * of longs representing stats. The array is TETHER_STATS_ARRAY_SIZE elements long and
- * the order of the elements is specified by the TETHER_STATS_{RX,TX}_{PACKETS,BYTES}
- * constants.
+ * @return an array of TetherStatsParcel, where each entry contains the upstream interface
+ * name and its tethering statistics.
+ * There will only ever be one entry for a given interface.
* @throws ServiceSpecificException in case of failure, with an error code indicating the
* cause of the the failure.
*/
- PersistableBundle tetherGetStats();
+ TetherStatsParcel[] tetherGetStats();
/**
* Add/Remove and IP address from an interface.
diff --git a/server/binder/android/net/TetherStatsParcel.aidl b/server/binder/android/net/TetherStatsParcel.aidl
new file mode 100644
index 0000000..25e200c
--- /dev/null
+++ b/server/binder/android/net/TetherStatsParcel.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+/**
+ * The statistics of tethering interface
+ *
+ * {@hide}
+ */
+parcelable TetherStatsParcel {
+ @utf8InCpp String iface;
+ long rxBytes;
+ long rxPackets;
+ long txBytes;
+ long txPackets;
+}