Android系统中对系统支持的feature都放在frameworks/base/data/etc/platform.xml中,以太网也属于其中一个feature。如果系统需要支持以太网卡的话,需要在platform.xml中添加以太网feature,代码如下:
Android启动过程中会调用readPermissionsFromXml方法来解析platform.xml文件。解析方法的路径为:frameworks\base\services\core\java\com\android\server\SystemConfig.java。
代码流程:EthernetNetworkFactory:start-->
updateInterfaceState-->
NetworkFactory:setScoreFilter-->
sendMessage(发送CMD_SET_SCORE消息)-->
NetworkFactory:handleSetScore-->
evalRequests-->
evalRequest-->
needNetworkFor-->
EthernetNetworkFactory: startNetwork() -->
onRequestNetwork(这个方法中会配置静态地址或者动态地址)-->
setStaticIpAddress(这个方法是配置静态地址的方法)
以上流程中代码修改的地方主要如下:
start方法:该方法中在获取系统的网络管理服务后,会遍历系统网络管理服务提供的接口,对于这些接口只会启动其中一个,在该方法中添加了下面代码,确保启动eth0这个接口。
双网卡共存和策略相关:
frameworks/base/core/java/android/net/NetworkFactory.java中的evalRequest修改如下:
frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory:
onRequestNetwork方法决定对某个以太网卡到底是分配静态地址还是使用DHCP分配地址。
onRequestNetwork中,config.getIpAssignment()方法获取当前网络的IP配置信息,来决定是否配置静态地址。顺着代码分析,发现这里的的config.getIpAssignment 最终是调用readIpAndProxyConfigurations(String filePath) 方法从"/misc/ethernet/ipconfig.txt"文件中获取IP信息的,config.getStaticIpConfiguration()自然也是从该配置文件中获取静态地址的信息。readIpAndProxyConfigurations的代码路径为frameworks/base/services/core/java/com/android/server/net/IpConfigStore.java。
起初的想法是只要能写一个ipconfig.txt的文件,就不用修改代码。网上到处找都没有找到对ipconfig.txt的描述,从代码反推来写该文件实验了几次也没成功,所以就在onRequestNetwork方法中增加了eth0的判断,只要是eth0就进行静态地址分配。
源码中是从ipconfig.txt中获取静态地址分配信息,我们没有构造出该文件,于是就修改了readIpAndProxyConfigurations(String filePath)这个方法,将以前从ipconfig.txt中获取的数据改为直接赋值,我们的目标是为eth0添加地址为192.168.1.77,掩码长度为24的静态IP地址,并且在该方法中已经将ipAssignment赋值为IpAssignment.STATIC了,所以上边代码中添加的判断eth0的地方就有点多余了。于是在setStaticIpAddress方法中就用用上边配置的地址信息为eth0配置静态地址。
EthernetNetworkFactory.java中将以太网卡的分值从70分修改为41分,这样当判断以太网访问Google的服务器(后来改成我们的服务器地址了)失败后减去惩罚分40的时候还剩下1分,不至于断开网络。
网络分值变化或者Capabilities变化时,就会重新进行分值比较,这时候会调用rematchAllNetworksAndRequests方法选出新的最优网络,代码路径为frameworks/base/services/core/java/com/android/server/ConnectivityService.java
rematchAllNetworksAndRequests中遍历网络agent,对每个网络agent最终调用rematchNetworkAndRequests方法,在该方法中涉及分值比较的地方都加了对以太网卡的判断,使以太网卡不参与分值比较。断开网络或者对网络信息进行修改的地方也同样增加了判断,如果是eth0则不执行对应的代码。
最早的策略配置方式是写了个shell脚本,配置了如下策略,对于目的IP为77/78的都走eth0网卡。在init.rc中开启对应的服务ipruleservice,网卡启动或者链路有变化调用该服务配置策略,ipruleservice中命令如下:
ip rule add to 192.168.1.78 table eth0
ip rule add to 192.168.1.77 table eth0
也可以将这种脚本服务配置策略的方式修改为legacyroutetohost方式,代码路径:frameworks/base/services/core/java/com/android/server/ConnectivityService.java文件中的updateLinkProperties方法。