service-t/jni/com_android_server_net_NetworkStats{Factory,Service}: improve jni
Note that we no longer need the (void*) casts, this is because: MAKE_JNI_NATIVE_METHOD() checks function args match MAKE_JNI_NATIVE_METHOD_AUTOSIG() autogenerates the signature Additionally: nativeGetTotalStat() nativeGetIfaceStat() nativeGetUidStat() should be faster now, by virtue of caching a bunch of calls. This more-or-less mirrors what was already done in the other file. Test: TreeHugger Flag: EXEMPT mainline Signed-off-by: Maciej Żenczykowski <maze@google.com> Change-Id: I5a715d15ca5c01b625b8b7a62bc0e10bc0cc213f
This commit is contained in:
parent
af5e799120
commit
3e2a811ecf
2 changed files with 98 additions and 103 deletions
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <jni.h>
|
||||
|
||||
#include <nativehelper/jni_macros.h>
|
||||
#include <nativehelper/JNIHelp.h>
|
||||
#include <nativehelper/ScopedUtfChars.h>
|
||||
#include <nativehelper/ScopedLocalRef.h>
|
||||
|
|
@ -64,9 +65,7 @@ static jobjectArray get_string_array(JNIEnv* env, jobject obj, jfieldID field, i
|
|||
{
|
||||
if (!grow) {
|
||||
jobjectArray array = (jobjectArray)env->GetObjectField(obj, field);
|
||||
if (array != NULL) {
|
||||
return array;
|
||||
}
|
||||
if (array) return array;
|
||||
}
|
||||
return env->NewObjectArray(size, gStringClass, NULL);
|
||||
}
|
||||
|
|
@ -75,9 +74,7 @@ static jintArray get_int_array(JNIEnv* env, jobject obj, jfieldID field, int siz
|
|||
{
|
||||
if (!grow) {
|
||||
jintArray array = (jintArray)env->GetObjectField(obj, field);
|
||||
if (array != NULL) {
|
||||
return array;
|
||||
}
|
||||
if (array) return array;
|
||||
}
|
||||
return env->NewIntArray(size);
|
||||
}
|
||||
|
|
@ -86,9 +83,7 @@ static jlongArray get_long_array(JNIEnv* env, jobject obj, jfieldID field, int s
|
|||
{
|
||||
if (!grow) {
|
||||
jlongArray array = (jlongArray)env->GetObjectField(obj, field);
|
||||
if (array != NULL) {
|
||||
return array;
|
||||
}
|
||||
if (array) return array;
|
||||
}
|
||||
return env->NewLongArray(size);
|
||||
}
|
||||
|
|
@ -101,40 +96,51 @@ static int statsLinesToNetworkStats(JNIEnv* env, jclass clazz, jobject stats,
|
|||
|
||||
ScopedLocalRef<jobjectArray> iface(env, get_string_array(env, stats,
|
||||
gNetworkStatsClassInfo.iface, size, grow));
|
||||
if (iface.get() == NULL) return -1;
|
||||
if (!iface.get()) return -1;
|
||||
|
||||
ScopedIntArrayRW uid(env, get_int_array(env, stats,
|
||||
gNetworkStatsClassInfo.uid, size, grow));
|
||||
if (uid.get() == NULL) return -1;
|
||||
if (!uid.get()) return -1;
|
||||
|
||||
ScopedIntArrayRW set(env, get_int_array(env, stats,
|
||||
gNetworkStatsClassInfo.set, size, grow));
|
||||
if (set.get() == NULL) return -1;
|
||||
if (!set.get()) return -1;
|
||||
|
||||
ScopedIntArrayRW tag(env, get_int_array(env, stats,
|
||||
gNetworkStatsClassInfo.tag, size, grow));
|
||||
if (tag.get() == NULL) return -1;
|
||||
if (!tag.get()) return -1;
|
||||
|
||||
ScopedIntArrayRW metered(env, get_int_array(env, stats,
|
||||
gNetworkStatsClassInfo.metered, size, grow));
|
||||
if (metered.get() == NULL) return -1;
|
||||
if (!metered.get()) return -1;
|
||||
|
||||
ScopedIntArrayRW roaming(env, get_int_array(env, stats,
|
||||
gNetworkStatsClassInfo.roaming, size, grow));
|
||||
if (roaming.get() == NULL) return -1;
|
||||
if (!roaming.get()) return -1;
|
||||
|
||||
ScopedIntArrayRW defaultNetwork(env, get_int_array(env, stats,
|
||||
gNetworkStatsClassInfo.defaultNetwork, size, grow));
|
||||
if (defaultNetwork.get() == NULL) return -1;
|
||||
if (!defaultNetwork.get()) return -1;
|
||||
|
||||
ScopedLongArrayRW rxBytes(env, get_long_array(env, stats,
|
||||
gNetworkStatsClassInfo.rxBytes, size, grow));
|
||||
if (rxBytes.get() == NULL) return -1;
|
||||
if (!rxBytes.get()) return -1;
|
||||
|
||||
ScopedLongArrayRW rxPackets(env, get_long_array(env, stats,
|
||||
gNetworkStatsClassInfo.rxPackets, size, grow));
|
||||
if (rxPackets.get() == NULL) return -1;
|
||||
if (!rxPackets.get()) return -1;
|
||||
|
||||
ScopedLongArrayRW txBytes(env, get_long_array(env, stats,
|
||||
gNetworkStatsClassInfo.txBytes, size, grow));
|
||||
if (txBytes.get() == NULL) return -1;
|
||||
if (!txBytes.get()) return -1;
|
||||
|
||||
ScopedLongArrayRW txPackets(env, get_long_array(env, stats,
|
||||
gNetworkStatsClassInfo.txPackets, size, grow));
|
||||
if (txPackets.get() == NULL) return -1;
|
||||
if (!txPackets.get()) return -1;
|
||||
|
||||
ScopedLongArrayRW operations(env, get_long_array(env, stats,
|
||||
gNetworkStatsClassInfo.operations, size, grow));
|
||||
if (operations.get() == NULL) return -1;
|
||||
if (!operations.get()) return -1;
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
ScopedLocalRef<jstring> ifaceString(env, env->NewStringUTF(lines[i].iface));
|
||||
|
|
@ -173,8 +179,7 @@ static int statsLinesToNetworkStats(JNIEnv* env, jclass clazz, jobject stats,
|
|||
static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats) {
|
||||
std::vector<stats_line> lines;
|
||||
|
||||
if (parseBpfNetworkStatsDetail(&lines) < 0)
|
||||
return -1;
|
||||
if (parseBpfNetworkStatsDetail(&lines) < 0) return -1;
|
||||
|
||||
return statsLinesToNetworkStats(env, clazz, stats, lines);
|
||||
}
|
||||
|
|
@ -182,25 +187,26 @@ static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats) {
|
|||
static int readNetworkStatsDev(JNIEnv* env, jclass clazz, jobject stats) {
|
||||
std::vector<stats_line> lines;
|
||||
|
||||
if (parseBpfNetworkStatsDev(&lines) < 0)
|
||||
return -1;
|
||||
if (parseBpfNetworkStatsDev(&lines) < 0) return -1;
|
||||
|
||||
return statsLinesToNetworkStats(env, clazz, stats, lines);
|
||||
}
|
||||
|
||||
static const JNINativeMethod gMethods[] = {
|
||||
{ "nativeReadNetworkStatsDetail", "(Landroid/net/NetworkStats;)I",
|
||||
(void*) readNetworkStatsDetail },
|
||||
{ "nativeReadNetworkStatsDev", "(Landroid/net/NetworkStats;)I",
|
||||
(void*) readNetworkStatsDev },
|
||||
MAKE_JNI_NATIVE_METHOD("nativeReadNetworkStatsDetail", "(Landroid/net/NetworkStats;)I", readNetworkStatsDetail),
|
||||
MAKE_JNI_NATIVE_METHOD("nativeReadNetworkStatsDev", "(Landroid/net/NetworkStats;)I", readNetworkStatsDev),
|
||||
};
|
||||
|
||||
int register_android_server_net_NetworkStatsFactory(JNIEnv* env) {
|
||||
int err = jniRegisterNativeMethods(env,
|
||||
"android/net/connectivity/com/android/server/net/NetworkStatsFactory", gMethods,
|
||||
NELEM(gMethods));
|
||||
if (jniRegisterNativeMethods(env,
|
||||
"android/net/connectivity/com/android/server/net/NetworkStatsFactory",
|
||||
gMethods,
|
||||
NELEM(gMethods))) abort();
|
||||
|
||||
gStringClass = env->FindClass("java/lang/String");
|
||||
if (!gStringClass) abort();
|
||||
gStringClass = static_cast<jclass>(env->NewGlobalRef(gStringClass));
|
||||
if (!gStringClass) abort();
|
||||
|
||||
jclass clazz = env->FindClass("android/net/NetworkStats");
|
||||
gNetworkStatsClassInfo.size = env->GetFieldID(clazz, "size", "I");
|
||||
|
|
@ -218,7 +224,7 @@ int register_android_server_net_NetworkStatsFactory(JNIEnv* env) {
|
|||
gNetworkStatsClassInfo.txPackets = env->GetFieldID(clazz, "txPackets", "[J");
|
||||
gNetworkStatsClassInfo.operations = env->GetFieldID(clazz, "operations", "[J");
|
||||
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
#include <jni.h>
|
||||
#include <nativehelper/jni_macros.h>
|
||||
#include <nativehelper/ScopedUtfChars.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
|
@ -39,73 +40,54 @@ using android::bpf::NetworkTraceHandler;
|
|||
|
||||
namespace android {
|
||||
|
||||
static struct {
|
||||
jclass theClass;
|
||||
jmethodID constructor;
|
||||
jfieldID rxBytes;
|
||||
jfieldID txBytes;
|
||||
jfieldID rxPackets;
|
||||
jfieldID txPackets;
|
||||
} gNetworkStatsEntry;
|
||||
|
||||
static void nativeRegisterIface(JNIEnv* env, jclass clazz, jstring iface) {
|
||||
ScopedUtfChars iface8(env, iface);
|
||||
if (iface8.c_str() == nullptr) return;
|
||||
if (!iface8.c_str()) return;
|
||||
bpfRegisterIface(iface8.c_str());
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Find the constructor.
|
||||
jmethodID constructorID = env->GetMethodID(gEntryClass, "<init>", "()V");
|
||||
if (constructorID == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Create a new instance of the Java class
|
||||
jobject result = env->NewObject(gEntryClass, constructorID);
|
||||
if (result == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
jobject result = env->NewObject(gNetworkStatsEntry.theClass, gNetworkStatsEntry.constructor);
|
||||
if (!result) 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);
|
||||
env->SetLongField(result, gNetworkStatsEntry.rxBytes, stats->rxBytes);
|
||||
env->SetLongField(result, gNetworkStatsEntry.txBytes, stats->txBytes);
|
||||
env->SetLongField(result, gNetworkStatsEntry.rxPackets, stats->rxPackets);
|
||||
env->SetLongField(result, gNetworkStatsEntry.txPackets, stats->txPackets);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static jobject nativeGetTotalStat(JNIEnv* env, jclass clazz) {
|
||||
StatsValue stats = {};
|
||||
|
||||
if (bpfGetIfaceStats(nullptr, &stats) == 0) {
|
||||
return statsValueToEntry(env, &stats);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
if (bpfGetIfaceStats(nullptr, &stats)) return nullptr;
|
||||
return statsValueToEntry(env, &stats);
|
||||
}
|
||||
|
||||
static jobject nativeGetIfaceStat(JNIEnv* env, jclass clazz, jstring iface) {
|
||||
ScopedUtfChars iface8(env, iface);
|
||||
if (iface8.c_str() == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!iface8.c_str()) return nullptr;
|
||||
|
||||
StatsValue stats = {};
|
||||
|
||||
if (bpfGetIfaceStats(iface8.c_str(), &stats) == 0) {
|
||||
return statsValueToEntry(env, &stats);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
if (bpfGetIfaceStats(iface8.c_str(), &stats)) return nullptr;
|
||||
return statsValueToEntry(env, &stats);
|
||||
}
|
||||
|
||||
static jobject nativeGetUidStat(JNIEnv* env, jclass clazz, jint uid) {
|
||||
StatsValue stats = {};
|
||||
|
||||
if (bpfGetUidStats(uid, &stats) == 0) {
|
||||
return statsValueToEntry(env, &stats);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
if (bpfGetUidStats(uid, &stats)) return nullptr;
|
||||
return statsValueToEntry(env, &stats);
|
||||
}
|
||||
|
||||
static void nativeInitNetworkTracing(JNIEnv* env, jclass clazz) {
|
||||
|
|
@ -113,37 +95,44 @@ static void nativeInitNetworkTracing(JNIEnv* env, jclass clazz) {
|
|||
}
|
||||
|
||||
static const JNINativeMethod gMethods[] = {
|
||||
{
|
||||
"nativeRegisterIface",
|
||||
"(Ljava/lang/String;)V",
|
||||
(void*)nativeRegisterIface
|
||||
},
|
||||
{
|
||||
"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
|
||||
},
|
||||
MAKE_JNI_NATIVE_METHOD_AUTOSIG("nativeRegisterIface", nativeRegisterIface),
|
||||
MAKE_JNI_NATIVE_METHOD("nativeGetTotalStat", "()Landroid/net/NetworkStats$Entry;", nativeGetTotalStat),
|
||||
MAKE_JNI_NATIVE_METHOD("nativeGetIfaceStat", "(Ljava/lang/String;)Landroid/net/NetworkStats$Entry;", nativeGetIfaceStat),
|
||||
MAKE_JNI_NATIVE_METHOD("nativeGetUidStat", "(I)Landroid/net/NetworkStats$Entry;", nativeGetUidStat),
|
||||
MAKE_JNI_NATIVE_METHOD_AUTOSIG("nativeInitNetworkTracing", nativeInitNetworkTracing),
|
||||
};
|
||||
|
||||
int register_android_server_net_NetworkStatsService(JNIEnv* env) {
|
||||
return jniRegisterNativeMethods(env,
|
||||
"android/net/connectivity/com/android/server/net/NetworkStatsService", gMethods,
|
||||
NELEM(gMethods));
|
||||
if (jniRegisterNativeMethods(env,
|
||||
"android/net/connectivity/com/android/server/net/NetworkStatsService",
|
||||
gMethods,
|
||||
NELEM(gMethods))) abort();
|
||||
|
||||
// Find the Java class that represents the structure
|
||||
jclass clazz = env->FindClass("android/net/NetworkStats$Entry");
|
||||
if (!clazz) abort();
|
||||
clazz = static_cast<jclass>(env->NewGlobalRef(clazz));
|
||||
if (!clazz) abort();
|
||||
gNetworkStatsEntry.theClass = clazz;
|
||||
|
||||
// Find the constructor.
|
||||
gNetworkStatsEntry.constructor = env->GetMethodID(clazz, "<init>", "()V");
|
||||
if (!gNetworkStatsEntry.constructor) abort();
|
||||
|
||||
// and the individual fields...
|
||||
gNetworkStatsEntry.rxBytes = env->GetFieldID(clazz, "rxBytes", "J");
|
||||
if (!gNetworkStatsEntry.rxBytes) abort();
|
||||
|
||||
gNetworkStatsEntry.txBytes = env->GetFieldID(clazz, "txBytes", "J");
|
||||
if (!gNetworkStatsEntry.txBytes) abort();
|
||||
|
||||
gNetworkStatsEntry.rxPackets = env->GetFieldID(clazz, "rxPackets", "J");
|
||||
if (!gNetworkStatsEntry.rxPackets) abort();
|
||||
|
||||
gNetworkStatsEntry.txPackets = env->GetFieldID(clazz, "txPackets", "J");
|
||||
if (!gNetworkStatsEntry.txPackets) abort();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue