修改Android5.1源码,配置以太网设置默认为静态ip

step 1:分析以太网启动流程:

本博客从以太网的服务注册开始,着急的看官直接Step 3 (。・∀・)ノ゙.

system_server进程中的服务启动方式有两种:

1.一种是通过SystemServiceManager的startService()。该方法用于启动继承于SystemService的服务。主要功能:创建serviceClass类的对象,将刚创建对象添加到SystemServiceManager的成员变量mServices,再调用刚创建对象的onStart()方法,方法中调用publishBinderService将service注册到ServiceManager。当SystemService到一定阶段,进入相应的Phase时,会调用SystemServiceManager的startBootPhase()回调方法,该方法会循环遍历所有向SystemServiceManager注册过的service的onBootPhase()方法,service针对各个阶段需要做怎样的处理或者是不做任何处理。

2.另一种是通过ServiceManager的addService(String name, IBinder service),该方法用于初始化继承于IBinder的服务。主要功能将该服务向Native层的service Manager注册服务。

以太网的Service启动属于第一种. 虽然文字描述相对抽象,但是由于以太网服务的草鸡简单,所以以太网Service的注册和启动完全不是事儿,OK,开启以太网Service服务(EthernetService)注册之旅.先上代码:

先来看看系统的进程的入口SystemServer ,main方法里通过SystemServiceManage启动EthernetService

//frameworks/base/services/Java/com/Android/server/SystemServer.java
	
	public final class SystemServer {  
	  private static final String ETHERNET_SERVICE_CLASS =  
		    "com.android.server.ethernet.EthernetService";  
	  public static void main(String[] args) {  
	    new SystemServer().run();  
	  }  
	  private void run() {  
	    startOtherServices();  
	  }  
	  private void startOtherServices() {  
	    if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET)) {  
		            mSystemServiceManager.startService(ETHERNET_SERVICE_CLASS);  
	    }  
	  } 

EthernetService 被启动之后就干了三件事儿:
1.构造函数中创建EthernetServiceImpl 对象
2.在onStart()方法 中将EthernetServiceImpl对象注册进了ServiceManager。
3.当系统进入到 PHASE_SYSTEM_SERVICES_READY时状态时,EthernetService的onBootPhase()方法被触发,调用EthernetServiceImpl .Start();

//frameworks/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() {
    // 将ServiceImpl注册到ServiceManager  
        Log.i(TAG, "Registering service " + Context.ETHERNET_SERVICE);
        publishBinderService(Context.ETHERNET_SERVICE, mImpl);
    }

    @Override
    public void onBootPhase(int phase) {
     //当系统运行到PHASE_SYSTEM_SERVICES_READY状态是时,Service启动EthernetServiceImpl   
        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
            mImpl.start();
        }
    }
}

step 2:分析源码如何读取以太网配置(IpConfiguration )

上面说到,EthernetService创建EthernetServiceImpl 对象.调用EthernetServiceImpl start方法.继续跟踪代码…

//frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetServiceImpl.java

public class EthernetServiceImpl extends IEthernetManager.Stub {
    private final EthernetConfigStore mEthernetConfigStore;
    //以太网配置信息类
    private IpConfiguration mIpConfiguration;
    private final EthernetNetworkFactory mTracker;
    private final RemoteCallbackList mListeners =
            new RemoteCallbackList();

    public EthernetServiceImpl(Context context) {
        mContext = context;
        Log.i(TAG, "Creating EthernetConfigStore");
        mEthernetConfigStore = new EthernetConfigStore();
        //读取以太网信息
        mIpConfiguration = mEthernetConfigStore.readIpAndProxyConfigurations();

        Log.i(TAG, "Read stored IP configuration: " + mIpConfiguration);

        mTracker = new EthernetNetworkFactory(mListeners);
    }
    public void start() {
        Log.i(TAG, "Starting Ethernet service");

        HandlerThread handlerThread = new HandlerThread("EthernetServiceThread");
        handlerThread.start();
        mHandler = new Handler(handlerThread.getLooper());

        mTracker.start(mContext, mHandler);

        mStarted.set(true);
/*      int ethernet_on = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ETHERNET_ON, 0);
        if(ethernet_on == 0 ) {
           setEthernetEnabled(false);
        }  */
    }
  • 可见 EthernetServiceImpl 构造函数中,通过mEthernetConfigStore.readIpAndProxyConfigurations()读取IpConfiguration .IPConfiguration 这个类是干啥的呢? IpConfiguration 这个类就是以太网配置信息类啊!!! 模式是DHCP啊还是静态啊,静态的ip ,网关啥的都存在这里头呢!!!胜利的曙光啊同志们!!!
//frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetConfigStore.java
public class EthernetConfigStore extends IpConfigStore {

    private static final String ipConfigFile =  Environment.getDataDirectory() +
            "/misc/ethernet/ipconfig.txt";

    public EthernetConfigStore() {
    }

    public IpConfiguration readIpAndProxyConfigurations() {
        SparseArray networks = readIpAndProxyConfigurations(ipConfigFile);

        if (networks.size() == 0) {
            Log.w(TAG, "No Ethernet configuration found. Using default.");
            return new IpConfiguration(IpAssignment.DHCP, ProxySettings.NONE, null, null);
        }

        if (networks.size() > 1) {
            // Currently we only support a single Ethernet interface.
            Log.w(TAG, "Multiple Ethernet configurations detected. Only reading first one.");
        }

        return networks.valueAt(0);
    }
  • 可知,ipconfig存储在 "data/misc/ethernet/ipconfig.txt"中。那么解决方案也就来了

step 3 配置以太网设置默认为静态ip

  • 1.手动配置好一份静态ip,这是ipconfig.txt中存储的就是静态ip了。

  • 2.取出以太网配置文件: ipconfig.txt
    进入命令行,输入
    adb root
    adb pull /data/misc/ethernet/ipconfig.txt
    这里写图片描述
    因为是在桌面输入的命令行,所以复制出的ipconfig.txt 的位置在桌面

  • 3.device.mk文件中 将 ipconfig.txt 预设置到固定位置
    1)将刚刚拷贝的ipconfig.txt 文件复制到与device.mk同目录下.
    2)找到一份源码编译时一定会编译的device.mk 文件,在device.mk中添加
    PRODUCT_COPY_FILES += $(LOCAL_PATH)/ipconfig.txt:system/etc/ipconfig.txt
    3)将上面提到的EthernetConfigStore 类中的ipConfigFile 修改为

 private static final String ipConfigFile = Environment.getRootDirectory() +
           "/etc/ipconfig.txt";

完活

step 4: 那么EthernetServiceImpl start方法是做什么的呢?

初步估计是关于网口连接时的广播注册,和 Binder 调用. 有个现象应该和他有关,在没有接网线之前,以太网显示状态位static ,但是没有ip ,网关 , 掩码等信息.调查ing

你可能感兴趣的:(android-源码,ethernet-ip)