Merge changes from topics "move-kerneltotag", "move-socket-tagging-to-mainline"
* changes: Move socket tagging implementation to mainline. Move kernelToTag to NetworkStatsFactory.
This commit is contained in:
@@ -39,7 +39,6 @@ filegroup {
|
||||
"src/android/net/TrafficStats.java",
|
||||
"src/android/net/UnderlyingNetworkInfo.*",
|
||||
"src/android/net/netstats/**/*.*",
|
||||
"src/com/android/server/NetworkManagementSocketTagger.java",
|
||||
],
|
||||
path: "src",
|
||||
visibility: [
|
||||
@@ -176,3 +175,34 @@ filegroup {
|
||||
"//packages/modules/Connectivity:__subpackages__",
|
||||
],
|
||||
}
|
||||
|
||||
cc_library_shared {
|
||||
name: "libframework-connectivity-tiramisu-jni",
|
||||
min_sdk_version: "30",
|
||||
cflags: [
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
"-Wno-unused-parameter",
|
||||
// Don't warn about S API usage even with
|
||||
// min_sdk 30: the library is only loaded
|
||||
// on S+ devices
|
||||
"-Wno-unguarded-availability",
|
||||
"-Wthread-safety",
|
||||
],
|
||||
srcs: [
|
||||
"jni/android_net_TrafficStats.cpp",
|
||||
"jni/onload.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"liblog",
|
||||
],
|
||||
static_libs: [
|
||||
"libnativehelper_compat_libc++",
|
||||
],
|
||||
stl: "none",
|
||||
apex_available: [
|
||||
"com.android.tethering",
|
||||
// TODO: remove when ConnectivityT moves to APEX.
|
||||
"//apex_available:platform",
|
||||
],
|
||||
}
|
||||
|
||||
46
framework-t/jni/android_net_TrafficStats.cpp
Normal file
46
framework-t/jni/android_net_TrafficStats.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include <android/file_descriptor_jni.h>
|
||||
#include <android/multinetwork.h>
|
||||
#include <nativehelper/JNIHelp.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
static jint tagSocketFd(JNIEnv* env, jclass, jobject fileDescriptor, jint tag, jint uid) {
|
||||
int fd = AFileDescriptor_getFd(env, fileDescriptor);
|
||||
if (fd == -1) return -EBADF;
|
||||
return android_tag_socket_with_uid(fd, tag, uid);
|
||||
}
|
||||
|
||||
static jint untagSocketFd(JNIEnv* env, jclass, jobject fileDescriptor) {
|
||||
int fd = AFileDescriptor_getFd(env, fileDescriptor);
|
||||
if (fd == -1) return -EBADF;
|
||||
return android_untag_socket(fd);
|
||||
}
|
||||
|
||||
static const JNINativeMethod gMethods[] = {
|
||||
/* name, signature, funcPtr */
|
||||
{ "native_tagSocketFd", "(Ljava/io/FileDescriptor;II)I", (void*) tagSocketFd },
|
||||
{ "native_untagSocketFd", "(Ljava/io/FileDescriptor;)I", (void*) untagSocketFd },
|
||||
};
|
||||
|
||||
int register_android_net_TrafficStats(JNIEnv* env) {
|
||||
return jniRegisterNativeMethods(env, "android/net/TrafficStats", gMethods, NELEM(gMethods));
|
||||
}
|
||||
|
||||
}; // namespace android
|
||||
|
||||
39
framework-t/jni/onload.cpp
Normal file
39
framework-t/jni/onload.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "FrameworkConnectivityJNI"
|
||||
|
||||
#include <log/log.h>
|
||||
#include <nativehelper/JNIHelp.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
int register_android_net_TrafficStats(JNIEnv* env);
|
||||
|
||||
extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
|
||||
JNIEnv *env;
|
||||
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "ERROR: GetEnv failed");
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
if (register_android_net_TrafficStats(env) < 0) return JNI_ERR;
|
||||
|
||||
return JNI_VERSION_1_6;
|
||||
}
|
||||
|
||||
}; // namespace android
|
||||
|
||||
@@ -31,12 +31,9 @@ import android.media.MediaPlayer;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.RemoteException;
|
||||
import android.os.StrictMode;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.server.NetworkManagementSocketTagger;
|
||||
|
||||
import dalvik.system.SocketTagger;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramSocket;
|
||||
@@ -56,6 +53,10 @@ import java.net.SocketException;
|
||||
* use {@link NetworkStatsManager} instead.
|
||||
*/
|
||||
public class TrafficStats {
|
||||
static {
|
||||
System.loadLibrary("framework-connectivity-tiramisu-jni");
|
||||
}
|
||||
|
||||
private static final String TAG = TrafficStats.class.getSimpleName();
|
||||
/**
|
||||
* The return value to indicate that the device does not support the statistic.
|
||||
@@ -232,9 +233,68 @@ public class TrafficStats {
|
||||
*/
|
||||
@SystemApi(client = MODULE_LIBRARIES)
|
||||
public static void attachSocketTagger() {
|
||||
NetworkManagementSocketTagger.install();
|
||||
dalvik.system.SocketTagger.set(new SocketTagger());
|
||||
}
|
||||
|
||||
private static class SocketTagger extends dalvik.system.SocketTagger {
|
||||
|
||||
// TODO: set to false
|
||||
private static final boolean LOGD = true;
|
||||
|
||||
SocketTagger() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tag(FileDescriptor fd) throws SocketException {
|
||||
final UidTag tagInfo = sThreadUidTag.get();
|
||||
if (LOGD) {
|
||||
Log.d(TAG, "tagSocket(" + fd.getInt$() + ") with statsTag=0x"
|
||||
+ Integer.toHexString(tagInfo.tag) + ", statsUid=" + tagInfo.uid);
|
||||
}
|
||||
if (tagInfo.tag == -1) {
|
||||
StrictMode.noteUntaggedSocket();
|
||||
}
|
||||
|
||||
if (tagInfo.tag == -1 && tagInfo.uid == -1) return;
|
||||
final int errno = native_tagSocketFd(fd, tagInfo.tag, tagInfo.uid);
|
||||
if (errno < 0) {
|
||||
Log.i(TAG, "tagSocketFd(" + fd.getInt$() + ", "
|
||||
+ tagInfo.tag + ", "
|
||||
+ tagInfo.uid + ") failed with errno" + errno);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void untag(FileDescriptor fd) throws SocketException {
|
||||
if (LOGD) {
|
||||
Log.i(TAG, "untagSocket(" + fd.getInt$() + ")");
|
||||
}
|
||||
|
||||
final UidTag tagInfo = sThreadUidTag.get();
|
||||
if (tagInfo.tag == -1 && tagInfo.uid == -1) return;
|
||||
|
||||
final int errno = native_untagSocketFd(fd);
|
||||
if (errno < 0) {
|
||||
Log.w(TAG, "untagSocket(" + fd.getInt$() + ") failed with errno " + errno);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static native int native_tagSocketFd(FileDescriptor fd, int tag, int uid);
|
||||
private static native int native_untagSocketFd(FileDescriptor fd);
|
||||
|
||||
private static class UidTag {
|
||||
public int tag = -1;
|
||||
public int uid = -1;
|
||||
}
|
||||
|
||||
private static ThreadLocal<UidTag> sThreadUidTag = new ThreadLocal<UidTag>() {
|
||||
@Override
|
||||
protected UidTag initialValue() {
|
||||
return new UidTag();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set active tag to use when accounting {@link Socket} traffic originating
|
||||
* from the current thread. Only one active tag per thread is supported.
|
||||
@@ -249,7 +309,7 @@ public class TrafficStats {
|
||||
* @see #clearThreadStatsTag()
|
||||
*/
|
||||
public static void setThreadStatsTag(int tag) {
|
||||
NetworkManagementSocketTagger.setThreadSocketStatsTag(tag);
|
||||
getAndSetThreadStatsTag(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -267,7 +327,9 @@ public class TrafficStats {
|
||||
* restore any existing values after a nested operation is finished
|
||||
*/
|
||||
public static int getAndSetThreadStatsTag(int tag) {
|
||||
return NetworkManagementSocketTagger.setThreadSocketStatsTag(tag);
|
||||
final int old = sThreadUidTag.get().tag;
|
||||
sThreadUidTag.get().tag = tag;
|
||||
return old;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -327,7 +389,7 @@ public class TrafficStats {
|
||||
* @see #setThreadStatsTag(int)
|
||||
*/
|
||||
public static int getThreadStatsTag() {
|
||||
return NetworkManagementSocketTagger.getThreadSocketStatsTag();
|
||||
return sThreadUidTag.get().tag;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -337,7 +399,7 @@ public class TrafficStats {
|
||||
* @see #setThreadStatsTag(int)
|
||||
*/
|
||||
public static void clearThreadStatsTag() {
|
||||
NetworkManagementSocketTagger.setThreadSocketStatsTag(-1);
|
||||
sThreadUidTag.get().tag = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -357,7 +419,7 @@ public class TrafficStats {
|
||||
*/
|
||||
@SuppressLint("RequiresPermission")
|
||||
public static void setThreadStatsUid(int uid) {
|
||||
NetworkManagementSocketTagger.setThreadSocketStatsUid(uid);
|
||||
sThreadUidTag.get().uid = uid;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -368,7 +430,7 @@ public class TrafficStats {
|
||||
* @see #setThreadStatsUid(int)
|
||||
*/
|
||||
public static int getThreadStatsUid() {
|
||||
return NetworkManagementSocketTagger.getThreadSocketStatsUid();
|
||||
return sThreadUidTag.get().uid;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -395,7 +457,7 @@ public class TrafficStats {
|
||||
*/
|
||||
@SuppressLint("RequiresPermission")
|
||||
public static void clearThreadStatsUid() {
|
||||
NetworkManagementSocketTagger.setThreadSocketStatsUid(-1);
|
||||
setThreadStatsUid(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,8 +22,6 @@ import static android.net.NetworkStats.TAG_ALL;
|
||||
import static android.net.NetworkStats.TAG_NONE;
|
||||
import static android.net.NetworkStats.UID_ALL;
|
||||
|
||||
import static com.android.server.NetworkManagementSocketTagger.kernelToTag;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
@@ -469,6 +467,19 @@ public class NetworkStatsFactory {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert {@code /proc/} tag format to {@link Integer}. Assumes incoming
|
||||
* format like {@code 0x7fffffff00000000}.
|
||||
*/
|
||||
public static int kernelToTag(String string) {
|
||||
int length = string.length();
|
||||
if (length > 10) {
|
||||
return Long.decode(string.substring(0, length - 8)).intValue();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse statistics from file into given {@link NetworkStats} object. Values
|
||||
* are expected to monotonically increase since device boot.
|
||||
|
||||
Reference in New Issue
Block a user