Merge changes Id26a24c8,I3b6ac97e into main am: e8184501b8
Original change: https://android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/2894583 Change-Id: I71bf4dc0c19f41946f4590a8e1698ca461c8426a Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
commit
c442143936
2 changed files with 86 additions and 73 deletions
|
|
@ -34,77 +34,64 @@
|
|||
|
||||
using android::bpf::bpfGetUidStats;
|
||||
using android::bpf::bpfGetIfaceStats;
|
||||
using android::bpf::bpfGetIfIndexStats;
|
||||
using android::bpf::NetworkTraceHandler;
|
||||
|
||||
namespace android {
|
||||
|
||||
// NOTE: keep these in sync with TrafficStats.java
|
||||
static const uint64_t UNKNOWN = -1;
|
||||
|
||||
enum StatsType {
|
||||
RX_BYTES = 0,
|
||||
RX_PACKETS = 1,
|
||||
TX_BYTES = 2,
|
||||
TX_PACKETS = 3,
|
||||
};
|
||||
|
||||
static uint64_t getStatsType(StatsValue* stats, StatsType type) {
|
||||
switch (type) {
|
||||
case RX_BYTES:
|
||||
return stats->rxBytes;
|
||||
case RX_PACKETS:
|
||||
return stats->rxPackets;
|
||||
case TX_BYTES:
|
||||
return stats->txBytes;
|
||||
case TX_PACKETS:
|
||||
return stats->txPackets;
|
||||
default:
|
||||
return UNKNOWN;
|
||||
static jobject statsValueToEntry(JNIEnv* env, StatsValue* stats) {
|
||||
// Find the Java class that represents the structure
|
||||
jclass gEntryClass = env->FindClass("android/net/NetworkStats$Entry");
|
||||
if (gEntryClass == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Create a new instance of the Java class
|
||||
jobject result = env->AllocObject(gEntryClass);
|
||||
if (result == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Set the values of the structure fields in the Java object
|
||||
env->SetLongField(result, env->GetFieldID(gEntryClass, "rxBytes", "J"), stats->rxBytes);
|
||||
env->SetLongField(result, env->GetFieldID(gEntryClass, "txBytes", "J"), stats->txBytes);
|
||||
env->SetLongField(result, env->GetFieldID(gEntryClass, "rxPackets", "J"), stats->rxPackets);
|
||||
env->SetLongField(result, env->GetFieldID(gEntryClass, "txPackets", "J"), stats->txPackets);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static jlong nativeGetTotalStat(JNIEnv* env, jclass clazz, jint type) {
|
||||
static jobject nativeGetTotalStat(JNIEnv* env, jclass clazz) {
|
||||
StatsValue stats = {};
|
||||
|
||||
if (bpfGetIfaceStats(NULL, &stats) == 0) {
|
||||
return getStatsType(&stats, (StatsType) type);
|
||||
return statsValueToEntry(env, &stats);
|
||||
} else {
|
||||
return UNKNOWN;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static jlong nativeGetIfaceStat(JNIEnv* env, jclass clazz, jstring iface, jint type) {
|
||||
static jobject nativeGetIfaceStat(JNIEnv* env, jclass clazz, jstring iface) {
|
||||
ScopedUtfChars iface8(env, iface);
|
||||
if (iface8.c_str() == NULL) {
|
||||
return UNKNOWN;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
StatsValue stats = {};
|
||||
|
||||
if (bpfGetIfaceStats(iface8.c_str(), &stats) == 0) {
|
||||
return getStatsType(&stats, (StatsType) type);
|
||||
return statsValueToEntry(env, &stats);
|
||||
} else {
|
||||
return UNKNOWN;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static jlong nativeGetIfIndexStat(JNIEnv* env, jclass clazz, jint ifindex, jint type) {
|
||||
StatsValue stats = {};
|
||||
if (bpfGetIfIndexStats(ifindex, &stats) == 0) {
|
||||
return getStatsType(&stats, (StatsType) type);
|
||||
} else {
|
||||
return UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static jlong nativeGetUidStat(JNIEnv* env, jclass clazz, jint uid, jint type) {
|
||||
static jobject nativeGetUidStat(JNIEnv* env, jclass clazz, jint uid) {
|
||||
StatsValue stats = {};
|
||||
|
||||
if (bpfGetUidStats(uid, &stats) == 0) {
|
||||
return getStatsType(&stats, (StatsType) type);
|
||||
return statsValueToEntry(env, &stats);
|
||||
} else {
|
||||
return UNKNOWN;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -113,11 +100,26 @@ static void nativeInitNetworkTracing(JNIEnv* env, jclass clazz) {
|
|||
}
|
||||
|
||||
static const JNINativeMethod gMethods[] = {
|
||||
{"nativeGetTotalStat", "(I)J", (void*)nativeGetTotalStat},
|
||||
{"nativeGetIfaceStat", "(Ljava/lang/String;I)J", (void*)nativeGetIfaceStat},
|
||||
{"nativeGetIfIndexStat", "(II)J", (void*)nativeGetIfIndexStat},
|
||||
{"nativeGetUidStat", "(II)J", (void*)nativeGetUidStat},
|
||||
{"nativeInitNetworkTracing", "()V", (void*)nativeInitNetworkTracing},
|
||||
{
|
||||
"nativeGetTotalStat",
|
||||
"()Landroid/net/NetworkStats$Entry;",
|
||||
(void*)nativeGetTotalStat
|
||||
},
|
||||
{
|
||||
"nativeGetIfaceStat",
|
||||
"(Ljava/lang/String;)Landroid/net/NetworkStats$Entry;",
|
||||
(void*)nativeGetIfaceStat
|
||||
},
|
||||
{
|
||||
"nativeGetUidStat",
|
||||
"(I)Landroid/net/NetworkStats$Entry;",
|
||||
(void*)nativeGetUidStat
|
||||
},
|
||||
{
|
||||
"nativeInitNetworkTracing",
|
||||
"()V",
|
||||
(void*)nativeInitNetworkTracing
|
||||
},
|
||||
};
|
||||
|
||||
int register_android_server_net_NetworkStatsService(JNIEnv* env) {
|
||||
|
|
|
|||
|
|
@ -1981,36 +1981,56 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||
if (callingUid != android.os.Process.SYSTEM_UID && callingUid != uid) {
|
||||
return UNSUPPORTED;
|
||||
}
|
||||
return nativeGetUidStat(uid, type);
|
||||
return getEntryValueForType(nativeGetUidStat(uid), type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getIfaceStats(@NonNull String iface, int type) {
|
||||
Objects.requireNonNull(iface);
|
||||
long nativeIfaceStats = nativeGetIfaceStat(iface, type);
|
||||
if (nativeIfaceStats == -1) {
|
||||
return nativeIfaceStats;
|
||||
final NetworkStats.Entry entry = nativeGetIfaceStat(iface);
|
||||
final long value = getEntryValueForType(entry, type);
|
||||
if (value == UNSUPPORTED) {
|
||||
return UNSUPPORTED;
|
||||
} else {
|
||||
// When tethering offload is in use, nativeIfaceStats does not contain usage from
|
||||
// offload, add it back here. Note that the included statistics might be stale
|
||||
// since polling newest stats from hardware might impact system health and not
|
||||
// suitable for TrafficStats API use cases.
|
||||
return nativeIfaceStats + getProviderIfaceStats(iface, type);
|
||||
entry.add(getProviderIfaceStats(iface));
|
||||
return getEntryValueForType(entry, type);
|
||||
}
|
||||
}
|
||||
|
||||
private long getEntryValueForType(@Nullable NetworkStats.Entry entry, int type) {
|
||||
if (entry == null) return UNSUPPORTED;
|
||||
switch (type) {
|
||||
case TrafficStats.TYPE_RX_BYTES:
|
||||
return entry.rxBytes;
|
||||
case TrafficStats.TYPE_TX_BYTES:
|
||||
return entry.txBytes;
|
||||
case TrafficStats.TYPE_RX_PACKETS:
|
||||
return entry.rxPackets;
|
||||
case TrafficStats.TYPE_TX_PACKETS:
|
||||
return entry.txPackets;
|
||||
default:
|
||||
return UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTotalStats(int type) {
|
||||
long nativeTotalStats = nativeGetTotalStat(type);
|
||||
if (nativeTotalStats == -1) {
|
||||
return nativeTotalStats;
|
||||
final NetworkStats.Entry entry = nativeGetTotalStat();
|
||||
final long value = getEntryValueForType(entry, type);
|
||||
if (value == UNSUPPORTED) {
|
||||
return UNSUPPORTED;
|
||||
} else {
|
||||
// Refer to comment in getIfaceStats
|
||||
return nativeTotalStats + getProviderIfaceStats(IFACE_ALL, type);
|
||||
entry.add(getProviderIfaceStats(IFACE_ALL));
|
||||
return getEntryValueForType(entry, type);
|
||||
}
|
||||
}
|
||||
|
||||
private long getProviderIfaceStats(@Nullable String iface, int type) {
|
||||
private NetworkStats.Entry getProviderIfaceStats(@Nullable String iface) {
|
||||
final NetworkStats providerSnapshot = getNetworkStatsFromProviders(STATS_PER_IFACE);
|
||||
final HashSet<String> limitIfaces;
|
||||
if (iface == IFACE_ALL) {
|
||||
|
|
@ -2019,19 +2039,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||
limitIfaces = new HashSet<>();
|
||||
limitIfaces.add(iface);
|
||||
}
|
||||
final NetworkStats.Entry entry = providerSnapshot.getTotal(null, limitIfaces);
|
||||
switch (type) {
|
||||
case TrafficStats.TYPE_RX_BYTES:
|
||||
return entry.rxBytes;
|
||||
case TrafficStats.TYPE_RX_PACKETS:
|
||||
return entry.rxPackets;
|
||||
case TrafficStats.TYPE_TX_BYTES:
|
||||
return entry.txBytes;
|
||||
case TrafficStats.TYPE_TX_PACKETS:
|
||||
return entry.txPackets;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return providerSnapshot.getTotal(null, limitIfaces);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -3398,10 +3406,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||
}
|
||||
}
|
||||
|
||||
private static native long nativeGetTotalStat(int type);
|
||||
private static native long nativeGetIfaceStat(String iface, int type);
|
||||
private static native long nativeGetIfIndexStat(int ifindex, int type);
|
||||
private static native long nativeGetUidStat(int uid, int type);
|
||||
// TODO: Read stats by using BpfNetMapsReader.
|
||||
@Nullable
|
||||
private static native NetworkStats.Entry nativeGetTotalStat();
|
||||
@Nullable
|
||||
private static native NetworkStats.Entry nativeGetIfaceStat(String iface);
|
||||
@Nullable
|
||||
private static native NetworkStats.Entry nativeGetUidStat(int uid);
|
||||
|
||||
/** Initializes and registers the Perfetto Network Trace data source */
|
||||
public static native void nativeInitNetworkTracing();
|
||||
|
|
|
|||
Loading…
Reference in a new issue