启动流程
启动日志
2025-07-16 10:12:04.185 609-609 SystemServerTiming system_server D StartEthernet
2025-07-16 10:12:04.185 609-609 SystemServiceManager system_server I Starting com.android.server.ethernet.EthernetService
2025-07-16 10:12:04.185 609-609 EthernetService system_server I Registering service ethernet
2025-07-16 10:12:04.494 609-609 SystemServerTiming system_server D OnBootPhase_480_com.android.server.ethernet.EthernetService
2025-07-16 10:12:04.512 609-609 SystemServerTiming system_server D OnBootPhase_500_com.android.server.ethernet.EthernetService
2025-07-16 10:12:04.512 609-609 EthernetServiceImpl system_server I Starting Ethernet service
2025-07-16 10:12:04.513 609-609 EthernetTracker system_server D Interface match regexp set to 'eth1'
2025-07-16 10:12:04.514 609-609 Ethernet system_server D Registering NetworkFactory
2025-07-16 10:12:04.514 609-715 ConnectivityService system_server D Got NetworkProvider Messenger for Ethernet
2025-07-16 10:12:04.515 609-609 IpConfigStore system_server E Error opening configuration file: java.io.FileNotFoundException: /data/misc/ethernet/ipconfig.txt: open failed: ENOENT (No such file or directory)
2025-07-16 10:12:04.515 609-753 EthernetTracker system_server I maybeTrackInterface: eth1
2025-07-16 10:12:04.573 609-624 EthernetTracker system_server I interfaceLinkStateChanged, iface: eth1, up: false
2025-07-16 10:12:04.574 609-753 EthernetTracker system_server D Tracking interface in client mode: eth1
2025-07-16 10:12:04.574 609-753 EthernetNetworkFactory system_server D addInterface, iface: eth1, capabilities: [ Transports: ETHERNET Capabilities: NOT_METERED&INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN&NOT_ROAMING&NOT_CONGESTED&NOT_SUSPENDED&NOT_VCN_MANAGED LinkUpBandwidth>=100000Kbps LinkDnBandwidth>=100000Kbps]
2025-07-16 10:12:04.574 609-753 EthernetNetworkFactory system_server D reconnecting Etherent
2025-07-16 10:12:04.574 609-753 EthernetNetworkFactory system_server D Starting Ethernet IpClient(eth1)
2025-07-16 10:12:04.603 609-609 SystemServerTiming system_server D OnBootPhase_520_com.android.server.ethernet.EthernetService
2025-07-16 10:12:04.825 609-609 SystemServerTiming system_server D OnBootPhase_550_com.android.server.ethernet.EthernetService
2025-07-16 10:12:04.926 609-609 SystemServerTiming system_server D OnBootPhase_600_com.android.server.ethernet.EthernetService
2025-07-16 10:12:04.956 609-609 SystemServerTiming system_server D ssm.onStartUser-0_com.android.server.ethernet.EthernetService
2025-07-16 10:12:05.790 609-753 EthernetNetworkFactory system_server D updateCapabilityFilter: [ Transports: ETHERNET Capabilities: NOT_METERED&INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN&NOT_ROAMING&NOT_CONGESTED&NOT_SUSPENDED&NOT_VCN_MANAGED]
2025-07-16 10:12:05.790 609-753 EthernetNe...FactoryExt system_server E get list of interfaces lo
2025-07-16 10:12:07.259 408-408 <no-tag> netd E RTL8211F Gigabit Ethernet stmmac-1:01: 2ns TX delay was already disabled (by pin-strapping RXD1 or bootloader configuration)
2025-07-16 10:12:07.260 408-408 <no-tag> netd E RTL8211F Gigabit Ethernet stmmac-1:01: Disabling 2ns RX delay (and changing the value from pin-strapping RXD0 or the bootloader)
2025-07-16 10:12:07.290 408-408 <no-tag> netd I rk_gmac-dwmac fe1c0000.ethernet eth0: PHY [stmmac-1:01] driver [RTL8211F Gigabit Ethernet] (irq=POLL)
2025-07-16 10:12:07.293 408-408 <no-tag> netd I rk_gmac-dwmac fe1c0000.ethernet eth0: No Safety Features support found
2025-07-16 10:12:07.293 408-408 <no-tag> netd I rk_gmac-dwmac fe1c0000.ethernet eth0: IEEE 1588-2008 Advanced Timestamp supported
2025-07-16 10:12:07.293 408-408 <no-tag> netd I rk_gmac-dwmac fe1c0000.ethernet eth0: registered PTP clock
2025-07-16 10:12:07.294 408-408 <no-tag> netd I rk_gmac-dwmac fe1c0000.ethernet eth0: configuring for phy/rgmii link mode
2025-07-16 10:12:05.854 609-624 EthernetTracker system_server I interfaceLinkStateChanged, iface: eth0, up: false
2025-07-16 10:12:05.854 609-624 EthernetTracker system_server I interfaceLinkStateChanged, iface: eth0, up: false
2025-07-16 10:12:05.854 609-753 EthernetNetworkFactory system_server D updateInterfaceLinkState, iface: eth1, up: false
2025-07-16 10:12:05.854 609-753 EthernetNe...FactoryExt system_server D interfaceLinkStateChanged: iface = eth1, mIface = eth0,up:false,mLinkUp:false
2025-07-16 10:12:05.854 609-753 EthernetNe...FactoryExt system_server D interfaceLinkStateChanged: iface = eth0, mIface = eth0,up:false,mLinkUp:false
2025-07-16 10:12:05.854 609-753 EthernetNe...FactoryExt system_server D interfaceLinkStateChanged: iface = eth0, mIface = eth0,up:false,mLinkUp:false
# 外网接入
2025-07-16 10:12:08.854 609-1201 EthernetTracker system_server D eth1 isEthernetInterfaceActive = true
2025-07-16 10:12:15.723 609-624 EthernetTracker system_server I interfaceLinkStateChanged, iface: eth1, up: true
2025-07-16 10:12:15.724 609-753 EthernetNetworkFactory system_server D updateInterfaceLinkState, iface: eth1, up: true
2025-07-16 10:12:15.793 609-753 EthernetNetworkFactory system_server D Starting Ethernet IpClient(eth1)
2025-07-16 10:12:15.794 609-753 EthernetNe...FactoryExt system_server D interfaceLinkStateChanged: iface = eth1, mIface = eth0,up:true,mLinkUp:false
2025-07-16 10:12:16.318 609-753 ConnectivityService system_server D registerNetworkAgent NetworkAgentInfo{network{100} handle{432902426637} ni{Ethernet CONNECTING extra: 3a:97:4c:27:bb:ee} Score(70 ; KeepConnected : 0 ; Policies : IS_UNMETERED) lp nc{[ Transports: ETHERNET Capabilities: NOT_METERED&INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN&NOT_ROAMING&FOREGROUND&NOT_CONGESTED&NOT_SUSPENDED&NOT_VCN_MANAGED LinkUpBandwidth>=100000Kbps LinkDnBandwidth>=100000Kbps]}}
2025-07-16 10:12:16.322 609-715 ConnectivityService system_server D [100 ETHERNET] EVENT_NETWORK_INFO_CHANGED, going from CONNECTING to CONNECTING
2025-07-16 10:12:16.322 609-715 ConnectivityService system_server D [100 ETHERNET] EVENT_NETWORK_INFO_CHANGED, going from CONNECTING to CONNECTED
2025-07-16 10:12:16.383 609-715 ConnectivityService system_server D Switching to new default network for: uid/pid:1000/609 activeRequest: 1 callbackRequest: 1 [NetworkRequest [ REQUEST id=1, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN&NOT_VCN_MANAGED RequestorUid: 1000 RequestorPkg: android] ]] callback flags: 1 priority: 2147483647 using NetworkAgentInfo{network{100} handle{432902426637} ni{Ethernet CONNECTED extra: 3a:97:4c:27:bb:ee} Score(70 ; KeepConnected : 0 ; Policies : IS_UNMETERED) lp nc{[ Transports: ETHERNET Capabilities: NOT_METERED&INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN&NOT_ROAMING&FOREGROUND&NOT_CONGESTED&NOT_SUSPENDED&NOT_VCN_MANAGED LinkUpBandwidth>=100000Kbps LinkDnBandwidth>=100000Kbps]}}
2025-07-16 10:12:16.409 609-715 ConnectivityService system_server D Sending CONNECTED broadcast for type 9 [100 ETHERNET] isDefaultNetwork=true
2025-07-16 10:12:16.415 609-715 ConnectivityService system_server D [100 ETHERNET] validation passed
# 内网接入
2025-07-16 10:22:33.060 609-624 EthernetTracker system_server I interfaceLinkStateChanged, iface: eth0, up: true
2025-07-16 10:22:33.060 609-753 EthernetNe...FactoryExt system_server D interfaceLinkStateChanged: iface = eth0, mIface = eth0,up:true,mLinkUp:false
2025-07-16 10:22:34.526 218-218 <no-tag> kworker/3 I rk_gmac-dwmac fe1c0000.ethernet eth0: Link is Up - 100Mbps/Full - flow control off
2025-07-16 10:22:34.061 609-2127 EthernetNe...FactoryExt system_server D IpClient.startProvisioning
2025-07-16 10:22:34.062 609-2127 EthernetNe...FactoryExt system_server D startDhcp success for eth0
2025-07-16 10:22:34.068 609-2128 EthernetNe...FactoryExt system_server D onLinkPropertiesChange
SystemServer.java
./java/com/android/server/SystemServer.java
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET) ||
mPackageManager.hasSystemFeature(PackageManager.FEATURE_USB_HOST)) {
t.traceBegin("StartEthernet");
mSystemServiceManager.startService(ETHERNET_SERVICE_CLASS);
t.traceEnd();
}
}
EthernetService.java
./opt/net/ethernet/java/com/android/server/ethernet/EthernetService.java
public final class EthernetService extends SystemService {
private static final String TAG = "EthernetService";
final EthernetServiceImpl mImpl;
public EthernetService(Context context) {
super(context);
mImpl = new EthernetServiceImpl(context);
}
@Override
public void onStart() {
Log.i(TAG, "Registering service " + Context.ETHERNET_SERVICE);
publishBinderService(Context.ETHERNET_SERVICE, mImpl);
}
@Override
public void onBootPhase(int phase) {
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
mImpl.start();
}
}
}
EthernetServiceImpl.java
./opt/net/ethernet/java/com/android/server/ethernet/EthernetServiceImpl.java
public class EthernetServiceImpl extends IEthernetManager.Stub {
public void start() {
Log.i(TAG, "Starting Ethernet service");
HandlerThread handlerThread = new HandlerThread("EthernetServiceThread");
handlerThread.start();
mHandler = new Handler(handlerThread.getLooper());
mTracker = new EthernetTracker(mContext, mHandler);
mTracker.start();
mStarted.set(true);
}
}
EthernetTracker.java
负责全局跟踪以太网接口(如 eth0/eth1)状态变化,并协调配置(如 DHCP/静态 IP)、通知系统连接状态,同时管理 EthernetNetworkFactory
./opt/net/ethernet/java/com/android/server/ethernet/EthernetTracker.java
final class EthernetTracker {
/**
* Interface names we track. This is a product-dependent regular expression, plus,
* if setIncludeTestInterfaces is true, any test interfaces.
*/
private String mIfaceMatch;
private final Context mContext;
private final INetworkManagementService mNMService;
private final INetd mNetd;
private final Handler mHandler;
private final EthernetNetworkFactory mFactory;
private final EthernetConfigStore mConfigStore;
private final WifiSleepController mWifiSleepController;
//lixiaogang add
private EthernetNetworkFactoryExt mEthernetNetworkFactoryExt;
EthernetTracker(Context context, Handler handler) {
mContext = context;
mHandler = handler;
// The services we use.
IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
mNMService = INetworkManagementService.Stub.asInterface(b);
mNetd = Objects.requireNonNull(NetdService.getInstance(), "could not get netd instance");
// Interface match regex.
updateIfaceMatchRegexp();
mConfigStore = new EthernetConfigStore();
NetworkCapabilities nc = createNetworkCapabilities(true /* clear default capabilities */);
mFactory = new EthernetNetworkFactory(handler, context, nc);
// 将这个网络工厂(NetworkFactory)注册到系统的 ConnectivityService,告知系统该工厂能够提供某类网络服务(如以太网),从而能够接收网络请求并管理网络连接。
mFactory.register();
mWifiSleepController = new WifiSleepController(mContext);
//lixiaogang add
mEthernetNetworkFactoryExt = new EthernetNetworkFactoryExt();
}
void start() {
mConfigStore.read();
// Default interface is just the first one we want to track.
mIpConfigForDefaultInterface = mConfigStore.getIpConfigurationForDefaultInterface();
final ArrayMap<String, IpConfiguration> configs = mConfigStore.getIpConfigurations();
// 将所有接口配置复制到 mIpConfigurations(当前运行时缓存的配置集合),以便随时访问和管理
for (int i = 0; i < configs.size(); i++) {
mIpConfigurations.put(configs.keyAt(i), configs.valueAt(i));
}
// 向网络管理服务(NetworkManagementService)注册一个观察者,用于监听网卡接口的增删、状态变化(up/down/link)事件。
try {
mNMService.registerObserver(new InterfaceObserver());
} catch (RemoteException e) {
Log.e(TAG, "Could not register InterfaceObserver " + e);
}
// 通过 Handler 异步执行 trackAvailableInterfaces() 方法,开始扫描和追踪当前系统已有的以太网接口。
mHandler.post(this::trackAvailableInterfaces);
}
// 获取外网接口
private void updateIfaceMatchRegexp() {
// modify lixiaogang start
// final String match = mContext.getResources().getString(
// com.android.internal.R.string.config_ethernet_iface_regex);
// mIfaceMatch = mIncludeTestInterfaces
// ? "(" + match + "|" + TEST_IFACE_REGEXP + ")"
// : match;
mIfaceMatch = SystemProperties.get("ro.net.eth_primary", "eth0");//"eth1";
Log.d(TAG, "Interface match regexp set to '" + mIfaceMatch + "'");
// modify lixiaogang end
}
private class InterfaceObserver extends BaseNetworkObserver {
@Override
public void interfaceLinkStateChanged(String iface, boolean up) {
if (DBG) {
Log.i(TAG, "interfaceLinkStateChanged, iface: " + iface + ", up: " + up);
}
if(isEthernetInterfaceActive())
mHandler.post(() -> updateInterfaceState(iface, up));
else{
if (iface.matches(mIfaceMatch)){
mHandler.post(() -> updateInterfaceState(iface, false));
Settings.System.putInt(mContext.getContentResolver(),Settings.System.ETHERNET_ON,0);
}}
mHandler.post(() -> mEthernetNetworkFactoryExt.interfaceLinkStateChanged(iface, up));
}
@Override
public void interfaceAdded(String iface) {
mHandler.post(() -> maybeTrackInterface(iface));
mHandler.post(() -> mEthernetNetworkFactoryExt.interfaceAdded(iface));
}
@Override
public void interfaceRemoved(String iface) {
mHandler.post(() -> stopTrackingInterface(iface));
mHandler.post(() -> mEthernetNetworkFactoryExt.interfaceRemoved(iface));
}
}
private boolean maybeTrackInterface(String iface) {
if (!iface.matches(mIfaceMatch)) {
return false;
}
// If we don't already track this interface, and if this interface matches
// our regex, start tracking it.
if (mFactory.hasInterface(iface) || iface.equals(mDefaultInterface)) {
if (DBG) Log.w(TAG, "Ignoring already-tracked interface " + iface);
return false;
}
if (DBG) Log.i(TAG, "maybeTrackInterface: " + iface);
// TODO: avoid making an interface default if it has configured NetworkCapabilities.
if (mDefaultInterface == null) {
mDefaultInterface = iface;
}
if (mIpConfigForDefaultInterface != null) {
updateIpConfiguration(iface, mIpConfigForDefaultInterface);
mIpConfigForDefaultInterface = null;
}
addInterface(iface);
mEthernetNetworkFactoryExt.start(mContext, mNMService);
return true;
}
private void trackAvailableInterfaces() {
try {
final String[] ifaces = mNMService.listInterfaces();
for (String iface : ifaces) {
if (maybeTrackInterface(iface)) {
String mIfaceTmp = iface;
new Thread(new Runnable() {
public void run() {
// carrier is always 1 when kernel boot up no matter RJ45 plugin or not,
// sleep a little time to wait kernel's correct carrier status
try {
Thread.sleep(3000);
} catch (InterruptedException ignore) {
}
Log.d(TAG, mIfaceTmp + " isEthernetInterfaceActive = " + isEthernetInterfaceActive());
if (!isEthernetInterfaceActive()) {
updateInterfaceState(mIfaceTmp, false);
}
}
}).start();
break;
}
}
} catch (RemoteException | IllegalStateException e) {
Log.e(TAG, "Could not get list of interfaces " + e);
}
}
}
EthernetConfigStore.java
用于持久化以太网配置信息的组件,其主要功能是:将以太网接口(如 eth0、eth1)的 IP 配置(如静态 IP、DNS、代理等)存储到 XML 文件中,并在系统启动时恢复这些配置。
/**
* This class provides an API to store and manage Ethernet network configuration.
*/
public class EthernetConfigStore {
private static final String ipConfigFile = Environment.getDataDirectory() +
"/misc/ethernet/ipconfig.txt";
private IpConfigStore mStore = new IpConfigStore();
private ArrayMap<String, IpConfiguration> mIpConfigurations;
private IpConfiguration mIpConfigurationForDefaultInterface;
private final Object mSync = new Object();
public EthernetConfigStore() {
mIpConfigurations = new ArrayMap<>(0);
}
public void read() {
synchronized (mSync) {
ArrayMap<String, IpConfiguration> configs =
IpConfigStore.readIpConfigurations(ipConfigFile);
// This configuration may exist in old file versions when there was only a single active
// Ethernet interface.
if (configs.containsKey("0")) {
mIpConfigurationForDefaultInterface = configs.remove("0");
}
mIpConfigurations = configs;
}
}
public void write(String iface, IpConfiguration config) {
boolean modified;
synchronized (mSync) {
if (config == null) {
modified = mIpConfigurations.remove(iface) != null;
} else {
IpConfiguration oldConfig = mIpConfigurations.put(iface, config);
modified = !config.equals(oldConfig);
}
if (modified) {
mStore.writeIpConfigurations(ipConfigFile, mIpConfigurations);
}
}
}
public ArrayMap<String, IpConfiguration> getIpConfigurations() {
synchronized (mSync) {
return new ArrayMap<>(mIpConfigurations);
}
}
@Nullable
public IpConfiguration getIpConfigurationForDefaultInterface() {
synchronized (mSync) {
return mIpConfigurationForDefaultInterface == null
? null : new IpConfiguration(mIpConfigurationForDefaultInterface);
}
}
}
EthernetNetworkFactory.java
EthernetNetworkFactory 负责代表“以太网”向 Android 系统注册并维护网络连接,创建 NetworkAgent,实现与 ConnectivityService 的双向连接与状态更新。
public class EthernetNetworkFactory extends NetworkFactory {
private final static int NETWORK_SCORE = 70;
private static final String NETWORK_TYPE = "Ethernet";
public EthernetNetworkFactory(Handler handler, Context context, NetworkCapabilities filter) {
super(handler.getLooper(), context, NETWORK_TYPE, filter);
mHandler = handler;
mContext = context;
setScoreFilter(NETWORK_SCORE);
mEthernetManager = (EthernetManager) context.getSystemService(Context.ETHERNET_SERVICE);
}
}
public class NetworkFactory {
public NetworkFactory(Looper looper, Context context, String logTag,
@Nullable final NetworkCapabilities filter) {
LOG_TAG = logTag;
if (isAtLeastS()) {
mImpl = new NetworkFactoryImpl(this, looper, context, filter);
} else {
mImpl = new NetworkFactoryLegacyImpl(this, looper, context, filter);
}
}
// 将这个网络工厂(NetworkFactory)注册到系统的 ConnectivityService,告知系统该工厂能够提供某类网络服务(如以太网),从而能够接收网络请求并管理网络连接。
public void register() {
mImpl.register(LOG_TAG);
}
}
class NetworkFactoryImpl extends NetworkFactoryLegacyImpl {
private void register(final String logTag, final boolean listenToAllRequests) {
if (mProvider != null) {
throw new IllegalStateException("A NetworkFactory must only be registered once");
}
if (DBG) mParent.log("Registering NetworkFactory");
mProvider = new NetworkProvider(mContext, NetworkFactoryImpl.this.getLooper(), logTag) {
@Override
public void onNetworkRequested(@NonNull NetworkRequest request, int score,
int servingProviderId) {
handleAddRequest(request);
}
@Override
public void onNetworkRequestWithdrawn(@NonNull NetworkRequest request) {
handleRemoveRequest(request);
}
};
((ConnectivityManager) mContext.getSystemService(
Context.CONNECTIVITY_SERVICE)).registerNetworkProvider(mProvider);
// The mScore and mCapabilityFilter members can only be accessed on the handler thread.
// TODO : offer a separate API to listen to all requests instead
if (listenToAllRequests) {
sendMessage(obtainMessage(CMD_LISTEN_TO_ALL_REQUESTS));
} else {
sendMessage(obtainMessage(CMD_OFFER_NETWORK));
}
}
}
工作流程图
sequenceDiagram
autonumber
participant PHY/Kernel as [🌐 物理网口/Kernel]
participant Netd as [🧩 Netd]
participant EthernetTracker as [🧠 EthernetTracker]
participant ConfigStore as [💾 EthernetConfigStore]
participant NetFactory as [🏗️ EthernetNetworkFactory]
participant IpClient as [📡 IpClient]
participant ConnSvc as [🧠 ConnectivityService]
PHY/Kernel->>Netd: 1. eth0 插入 (link up)
Netd->>EthernetTracker: 2. interfaceAdded("eth0")
EthernetTracker->>ConfigStore: 3. 读取 eth0 配置
ConfigStore-->>EthernetTracker: 返回 IpConfiguration
EthernetTracker->>NetFactory: 4. maybeStartNetwork("eth0")
NetFactory->>IpClient: 5. 启动 DHCP / 静态 IP 配置
IpClient-->>NetFactory: 6. Provisioning 成功 (onProvisioningSuccess)
NetFactory->>ConnSvc: 7. 创建 NetworkAgent
ConnSvc-->>NetFactory: 注册完成
ConnSvc->>System: 8. 设置 eth0 为默认网络(如优先级最高)
Note over EthernetTracker,NetFactory: 后续如接口 down,将自动触发 maybeStopNetwork()
编号 | 步骤解释 |
---|---|
1 | 用户插上网线或插入 USB 网卡,驱动创建 eth0 接口 |
2 | Netd 通过 INetworkManagementService 通知上层有新接口 |
3 | EthernetTracker 查询该接口的配置(静态 IP / DHCP) |
4 | 如果接口为 up,调用 EthernetNetworkFactory 建立连接 |
5 | IpClient 执行实际 IP 分配(DHCP)或设置静态 IP |
6 | IP 成功配置后,通知连接可用 |
7 | EthernetNetworkFactory 创建 NetworkAgent ,注册到 ConnectivityService |
8 | 系统根据优先级将 eth0 设置为默认网络,并向 apps 广播连接可用 |