Android10 添加以太网网络共享功能

文章目录

  • [Android10 添加以太网网络共享功能](#Android10 添加以太网网络共享功能)
    • 一、前言
    • 二、需求分析
    • 三、系统架构与原理
      • [3.1 整体架构](#3.1 整体架构)
      • [3.2 代码执行流程](#3.2 代码执行流程)
      • [3.3 IP 网段分配](#3.3 IP 网段分配)
    • 四、修改文件概览
    • 五、详细实现
      • [5.1 定义 Tethering 类型](#5.1 定义 Tethering 类型)
      • [5.2 增加以太网状态广播](#5.2 增加以太网状态广播)
      • [5.3 Tethering 核心逻辑改造](#5.3 Tethering 核心逻辑改造)
        • [5.3.1 接口类型识别](#5.3.1 接口类型识别)
        • [5.3.2 自动开启以太网共享](#5.3.2 自动开启以太网共享)
        • [5.3.3 共享开关实现](#5.3.3 共享开关实现)
        • [5.3.4 状态广播与清理](#5.3.4 状态广播与清理)
      • [5.4 配置识别与 IP 分配](#5.4 配置识别与 IP 分配)
        • [5.4.1 接口识别规则](#5.4.1 接口识别规则)
        • [5.4.2 网关 IP 配置](#5.4.2 网关 IP 配置)
      • [5.5 阻止正常网络代理流程](#5.5 阻止正常网络代理流程)
    • 六、关键逻辑说明
    • 七、总结

Android10 添加以太网网络共享功能

摘要:本文记录在 Android10 AOSP 源码中新增以太网网络共享(Ethernet Tethering)的完整修改过程。通过扩展系统 Tethering 框架,使设备可通过 eth0 接口为下游设备提供网络共享服务,适用于工业网关、有线热点等场景。

一、前言

Android 原生系统支持 WiFi、USB、蓝牙三种网络共享方式,但在部分行业设备(如工控平板、车载网关)中,存在通过有线以太网口对外共享网络的需求。Android10 的 Tethering 框架具备良好的扩展性,本文介绍如何在 AOSP 源码中新增 Ethernet Tethering 支持,实现插入网线后自动开启以太网共享。

二、需求分析

核心需求可拆解为以下几点:

  1. 新增 Tethering 类型 :在系统层定义 TETHERING_ETHERNET,让框架识别以太网共享。
  2. 接口状态监听 :监听 eth0 插拔事件,网线接入后自动触发共享逻辑。
  3. 状态广播:向上层应用提供以太网连接状态广播,便于 UI 展示。
  4. IP 地址分配 :为 eth0 分配固定的网关地址,并启动 DHCP 服务为下游设备分配 IP。
  5. 避免冲突 :阻止 eth0 走正常的以太网网络连接流程,防止与 Tethering 逻辑冲突。

最终效果:

通过网线连接PC和设备

Android设备IP:

PC 设备IP

三、系统架构与原理

3.1 整体架构

在 Android 网络体系中,Tethering 模块位于 ConnectivityService 之下、Netd 之上,负责管理所有下游共享接口。本次修改的整体架构如下:

复制代码
┌─────────────────────────────────────────┐
│           应用层 (SystemUI/APK)          │
│     接收 ETHERNET_STATE 广播展示状态      │
└──────────────────┬──────────────────────┘
                   │
┌──────────────────▼──────────────────────┐
│         Framework API 层                │
│  ConnectivityManager / EthernetManager  │
│  (新增 TETHERING_ETHERNET 常量与广播)    │
└──────────────────┬──────────────────────┘
                   │
┌──────────────────▼──────────────────────┐
│         System Server 层                 │
│  ┌─────────────────────────────────┐    │
│  │   Tethering.java (状态机核心)    │    │
│  │   • 监听 eth0 插拔事件            │    │
│  │   • 自动 enable/disable 共享     │    │
│  │   • 发送状态广播                  │    │
│  └─────────────────────────────────┘    │
│  ┌─────────────────────────────────┐    │
│  │   IpServer.java (地址服务)       │    │
│  │   • 配置 192.168.48.1/24        │    │
│  │   • 启动 Dnsmasq DHCP 服务       │    │
│  └─────────────────────────────────┘    │
│  ┌─────────────────────────────────┐    │
│  │ EthernetNetworkFactory.java      │    │
│  │   • 拦截 eth0 正常上网流程       │    │
│  └─────────────────────────────────┘    │
└──────────────────┬──────────────────────┘
                   │
┌──────────────────▼──────────────────────┐
│           Native 层 (Netd)              │
│     接口状态上报 / iptables 规则下发      │
└─────────────────────────────────────────┘

3.2 代码执行流程

当网线插入设备后,整个共享开启的代码执行流程如下:
匹配 eth0
网线插入 eth0
Kernel 触发 netlink 事件
Netd 上报 interfaceLinkStateChanged
Tethering.interfaceStatusChanged
ifaceNameToType

判断接口类型
识别为 TETHERING_ETHERNET
发送 ACTION_ETHERNET_STATE

Sticky 广播
调用 enableTetheringInternal
进入 setEthernetTethering
调用 tetherMatchingInterfaces
IpServer 进入 STATE_TETHERED
配置 192.168.48.1/24
启动 DHCP + DNS 转发
下游设备通过网线获取 IP 上网

3.3 IP 网段分配

为避免与系统已有的 WiFi 热点、Wigig 共享地址冲突,各共享类型使用独立网段:

共享类型 接口示例 网关地址 子网掩码 DHCP 网段
WiFi wlan0 192.168.42.1 /24 192.168.42.0/24
Ethernet eth0 192.168.48.1 /24 192.168.48.0/24
Wigig wigig0 192.168.50.1 /24 192.168.50.0/24

四、修改文件概览

文件路径 修改说明
frameworks/base/core/java/android/net/ConnectivityManager.java 新增 TETHERING_ETHERNET 常量
frameworks/base/core/java/android/net/EthernetManager.java 新增以太网状态广播 Action 与 Extra
frameworks/base/core/res/AndroidManifest.xml 注册 protected broadcast
frameworks/base/services/core/java/com/android/server/connectivity/Tethering.java Tethering 核心逻辑,自动开启/关闭以太网共享
frameworks/base/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java 新增 isEthernet() 接口识别
frameworks/base/services/net/java/android/net/ip/IpServer.java 配置以太网网关 IP 及子网掩码
frameworks/base/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java 阻止 eth0 进入正常网络连接流程

五、详细实现

5.1 定义 Tethering 类型

首先,在 ConnectivityManager 中新增以太网共享类型常量,值为 4

java 复制代码
// frameworks/base/core/java/android/net/ConnectivityManager.java
/**
 * Ethernet tethering type.
 * @see #startTethering(int, OnStartTetheringCallback, boolean)
 * @hide
 */
public static final int TETHERING_ETHERNET = 4;

5.2 增加以太网状态广播

为了让应用层能感知以太网共享的插拔状态,在 EthernetManager 中定义广播 Action 与 Extra:

java 复制代码
// frameworks/base/core/java/android/net/EthernetManager.java
/**
 * Broadcast Action: A sticky broadcast for ethernet state change events when in device mode.
 * {@hide}
 */
public static final String ACTION_ETHERNET_STATE =
        "android.net.action.ETHERNET_STATE";

/**
 * Boolean extra indicating whether ethernet is connected or disconnected.
 * {@hide}
 */
public static final String ETHERNET_CONNECTED = "connected";

同时,在 AndroidManifest.xml 中将其注册为受保护广播,避免第三方应用滥用:

xml 复制代码
<!-- frameworks/base/core/res/AndroidManifest.xml -->
<<protected-broadcast android:name="android.net.action.ETHERNET_STATE" />

5.3 Tethering 核心逻辑改造

Tethering.java 是本次修改的核心文件,主要完成以下工作:

5.3.1 接口类型识别

ifaceNameToType() 中增加对 eth0 的识别:

java 复制代码
// frameworks/base/services/core/java/com/android/server/connectivity/Tethering.java
private int ifaceNameToType(String iface) {
    final TetheringConfiguration cfg = mConfig;
    if (cfg.isWifi(iface)) {
        // ...
        return TETHERING_WIGIG;
    } else if (cfg.isUsb(iface)) {
        return TETHERING_USB;
    } else if (cfg.isBluetooth(iface)) {
        return TETHERING_BLUETOOTH;
    } else if (cfg.isEthernet(iface)) {
        return TETHERING_ETHERNET;
    }
    return TETHERING_INVALID;
}
5.3.2 自动开启以太网共享

interfaceStatusChanged() 中监听接口状态变化。当检测到 eth0 链路 Up 时,发送状态广播,并自动调用内部开启逻辑:

java 复制代码
// frameworks/base/services/core/java/com/android/server/connectivity/Tethering.java
public void interfaceStatusChanged(String iface, boolean up) {
    // ... 原有 WiFi/USB/蓝牙逻辑 ...

    int interfaceType = ifaceNameToType(iface);
    if (interfaceType == TETHERING_ETHERNET) {
        // 发送以太网插拔状态广播
        final Intent broadcast = new Intent(EthernetManager.ACTION_ETHERNET_STATE);
        broadcast.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING |
                Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
        broadcast.putExtra(EthernetManager.ETHERNET_CONNECTED, up);
        mContext.sendStickyBroadcastAsUser(broadcast, UserHandle.ALL);

        // 自动开启以太网共享
        enableTetheringInternal(interfaceType, true, null);
    }
}
5.3.3 共享开关实现

enableTetheringInternal() 中增加 TETHERING_ETHERNET 分支:

java 复制代码
case TETHERING_ETHERNET:
    result = setEthernetTethering(enable);
    sendTetherResult(receiver, result);
    break;

setEthernetTethering() 的实现如下:

java 复制代码
// frameworks/base/services/core/java/com/android/server/connectivity/Tethering.java
public int setEthernetTethering(boolean enable) {
    synchronized (mPublicSync) {
        if (enable) {
            final long ident = Binder.clearCallingIdentity();
            try {
                tetherMatchingInterfaces(IpServer.STATE_TETHERED, TETHERING_ETHERNET);
            } finally {
                Binder.restoreCallingIdentity(ident);
            }
        } else {
            final long ident = Binder.clearCallingIdentity();
            try {
                tetherMatchingInterfaces(IpServer.STATE_AVAILABLE, TETHERING_ETHERNET);
            } finally {
                Binder.restoreCallingIdentity(ident);
            }
        }
    }
    return TETHER_ERROR_NO_ERROR;
}
5.3.4 状态广播与清理

sendTetherStateChangedBroadcast() 中增加以太网共享状态标记,并在 untetherAll() 中增加停止逻辑:

java 复制代码
// frameworks/base/services/core/java/com/android/server/connectivity/Tethering.java
public void untetherAll() {
    stopTethering(TETHERING_WIFI);
    stopTethering(TETHERING_USB);
    stopTethering(TETHERING_ETHERNET);
    stopTethering(TETHERING_BLUETOOTH);
}

5.4 配置识别与 IP 分配

5.4.1 接口识别规则

TetheringConfiguration 中增加以太网接口判断,当前固定匹配 eth0

java 复制代码
// frameworks/base/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
public boolean isEthernet(String iface) {
    return iface.equals("eth0");
}
5.4.2 网关 IP 配置

IpServer 中,为以太网共享接口分配独立的网段,避免与 WiFi 热点冲突:

java 复制代码
// frameworks/base/services/net/java/android/net/ip/IpServer.java
private static final String ETHERNET_IFACE_ADDR = "192.168.48.1";
private static final int ETHERNET_PREFIX_LENGTH = 24;

configureIPv4() 中根据接口类型选择对应地址:

java 复制代码
if (mInterfaceType == ConnectivityManager.TETHERING_WIFI) {
    ipAsString = WIFI_HOST_IFACE_ADDR;
    prefixLen = WIFI_HOST_IFACE_PREFIX_LENGTH;
} else if (mInterfaceType == ConnectivityManager.TETHERING_ETHERNET) {
    ipAsString = ETHERNET_IFACE_ADDR;
    prefixLen = ETHERNET_PREFIX_LENGTH;
} else if (mInterfaceType == ConnectivityManager.TETHERING_WIGIG) {
    // ...
}

5.5 阻止正常网络代理流程

eth0 作为共享下游接口时,必须阻止其进入 EthernetNetworkFactory 的正常网络连接流程(如 DHCP 获取、网络评分等),否则会导致 Tethering 与正常网络栈冲突。

EthernetNetworkFactorystart() 方法中增加路由模式判断:

java 复制代码
// frameworks/base/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java
private void start() {
    // 若当前处于以太网路由/共享模式,则不启动正常网络连接
    boolean isEthernetRouterMode = true; 
    // 实际项目中建议通过 Settings.Global 控制:
    // Settings.Global.getInt(mContext.getContentResolver(), ETHERNET_ROUTER_MODE_ON, 0) == 1;
    
    if (isEthernetRouterMode) {
        return;
    }

    if (mIpClient != null) {
        if (DBG) Log.d(TAG, "IpClient already started");
        return;
    }
    // ... 原有网络连接逻辑
}

六、关键逻辑说明

  1. 自动触发机制 :系统通过 Netd 监听内核网卡事件,Tethering 服务收到 eth0interfaceLinkStateChanged 回调后,自动完成共享开启,无需用户手动操作。
  2. StickyBroadcast:使用粘性广播发送以太网状态,确保应用注册接收器后能立即获取当前连接状态。
  3. 网段隔离 :以太网共享使用 192.168.48.0/24 网段,与 WiFi 热点的 192.168.42.0/24、Wigig 的 192.168.50.0/24 相互独立,避免路由冲突。
  4. 流程拦截EthernetNetworkFactory 中的拦截是本次功能生效的关键,若缺少此步骤,eth0 会被系统当作普通以太网上行接口进行 DHCP,导致 Tethering 无法正常分配地址。

七、总结

本文通过在 Android10 Tethering 框架中新增 TETHERING_ETHERNET 类型,实现了以太网口的有线网络共享功能。主要改动集中在:

  • Framework API 层:新增常量与广播定义;
  • SystemServer 层:改造 Tethering 状态机,实现自动识别与开启;
  • 网络协议层:配置独立网段与 DHCP 服务;
  • 冲突规避层 :拦截 EthernetNetworkFactory 的正常连接流程。

该方案已应用于实际项目,可满足工业设备、车载网关等场景下通过有线网口对外提供网络共享的需求。

相关推荐
修炼者3 小时前
bitmap和drawable的互相转换
android
美狐美颜SDK开放平台4 小时前
美颜SDK接入流程详解:Android、iOS、鸿蒙兼容方案解析
android·人工智能·ios·华为·harmonyos·美颜sdk·视频美颜sdk
笔夏5 小时前
【安卓学习之FloatingActionButton】按钮太小
android·学习
XD7429716366 小时前
科技早报晚报|2026年5月15日:无摄像头空间感知、Android 设备实验室与视频检索代理,今天更值得跟进的 3 个技术机会
android·科技·音视频·开源项目·边缘ai·开发者工具
应用市场6 小时前
Android Verified Boot 2.0 安全启动原理详解
android·安全
只可远观6 小时前
Android XML命令式和Jetpack Compose声明式UI
android·xml
他是龙5516 小时前
DVWA 靶场深度解析:文件包含 & 文件上传(Low → Impossible)
android
_李小白7 小时前
【Android车载学习笔记】第一天:Android Automotive OS介绍
android·笔记
aqi007 小时前
FFmpeg开发笔记(一百零一)跨平台的开源音视频移动框架MobileFFmpeg
android·ffmpeg·音视频·直播·流媒体