当前位置: 移动技术网 > 移动技术>移动开发>Android > Android以太网框架情景分析之启动简介

Android以太网框架情景分析之启动简介

2020年07月17日  | 移动技术网移动技术  | 我要评论

        Android以太网框架情景分析之启动简介



前言

  以太网在Android各种终端设备形态中是一个小众化的东西,通常出现在各种多媒体,机顶盒等特殊设备形态下,既然有需求,并且正好最近这阵子我也在调试以太网相关的东西,所以就分析分析以太网的框架结构。如果仅仅是添加以太网的相关功能,还是比较简单的,但是如果想真的搞懂以太网及其涉及到的Android网络框架还是比较复杂的。

  本篇章演示的源码是在Android 7.1 msm8953平台上,其中涉及的源码路径如下所示:


frameworks/base/services/java/com/android/server/
	---ConnectivityService.java
	---INativeDaemonConnectorCallbacks.java
	---NativeDaemonConnector.java
	---NetworkManagementService.java
	---SystemServer.java
	---SystemServiceManager.java

frameworks/base/core/java/android/net/
	---ConnectivityManager.java
	---EthernetManager.java
	---IConnectivityManager.aidl
	---IEthernetManager.aidl
	---LinkProperties.java
	---NetworkPolicy.java
	---NetworkAgent.java
	---NetworkFactory.java
	---NetworkInfo.java
	---ProxyInfo.java

frameworks/opt/net/ethernet/java/com/android/server/ethernet/
	---EthernetConfigStore.java
	---EthernetNetworkFactory.java
	---EthernetServiceImpl.java
	---EthernetService.java


开篇

  对于Android以太网框架情景分析这个篇章,我将会从三个维度来进行分析分别如下,本来是打算将以太网框架情景分析的放在一个篇章中,但是发现由于涉及的知识点太多了,真的搞不下,所以只能做成一个系列了。

  • 以太网服务(EthernetService)启动及注册流程
  • 应用层面添加和使用以太网服务相关功能接口层面
  • 以太网服务和ConnectivityService,Netd交互层面,这个也是最复杂的,最难的

我们已经从整体上概括了我们本篇章要讲解的维度了,我们先从整体流程图来看下这个三个维度,流程图如下所示:

在这里插入图片描述



一.前期知识储备

  在正式开始分析以太网服务启动流程之前,我们得先储备一些基本的关于以太网以及Android Framework及Native层的网络框架知识点,这样才能做到磨刀不误砍柴工。


1.1 Android Framework中网络相关的4大Service

  这四个服务涉及的内容非常多,这个不影响本篇的分析,这个会在后续有时间需要专门的篇章来分析,虽然整理了一些资料,并且详尽的分析了,但是总感觉还不到位,所以这个还需要时日。

1.1.1 ConnectivityService

  ConnectivityService是系统网络连接管理服务,也是整个整个Android Framework层网络框架的核心类。主要处理APP网络监听和请求,通知网络变化;处理WiFi/Telephony/Ethernet等各个链路的网络注册,更新链路信息;网络检测/评分与网络选择。

1.1.2 NetworkPolicyManagerService

  NetworkPolicyManagerService是网络策略管理服务,这些策略一般指对APP的网络和限制和放行,通过netfilter来实现。

1.1.3 NetworkManagementService

  NetworkManagementService是网络管理服务。NetworkManagementService为ConnectivityService和其他Framework中的服务建立了与Netd之间通信的渠道,NetworkPolicyManagerService对各个UID的策略最终都会通过 NetworkManagementService向Netd发送;另外,NetworkManagementService还会监听Netd服务的状态,处理Socket返回的消息,如 Bandwidth/Iface/Route/Address/Dns Server等的变化,同时将这些变化通知“感兴趣”的模块。

1.1.4 NetworkStatsService

  这个服务主要收集网络数据,如各个Iface上下行网络流量的字节数等。APP或者其他服务可以通过该服务获取网络流量信息等。


1.2 Netd守护进程

  Netd 负责Android网络的管理和控制。监听Kernel消息并通知NMPS;防火墙设置(Firewall);处理网络地址转换(NAT);进行网络共享配置(Tethering,如softap,usb网络共享)等。这个只先做简单介绍,后续会有专门章节讲解。



二. 以太网服务(EthernetService)启动流程

  在前面的篇章中Android 9 §系统启动之SystemServer大揭秘(虽然Android的版本有所区别,但是其他其它服务的逻辑部分基本相同)中我们讲解了system_server进程在启动的过程中会在startOtherServices启动其它服务,这其中就包括了以太网(EthernetService)服务。下面我们就按照这个流程来一一介绍。


2.1 SystemServer.startOtherServices

  通过前面的分析我们知道EthernetService是在system_server进程的startOtherServices的方法中启动的,下面让我们看就着代码分析一下,源码的路径为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() {
  	//feather特性,这个通常定义在Android源码的frameworks/native/data/etc中
    if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET)) {
                    mSystemServiceManager.startService(ETHERNET_SERVICE_CLASS);
    }
  }
}

  这里补充一点就是Android的feather特性通常定义在frameworks/native/data/etc中,这里不做过多的说明,可以参见博客Android Feature特性。这里借助SystemServiceManager的startService方法通过类名启动了EthernetService服务,关于SystemServiceManager在前面篇章的system_server进程启动的章节中有过介绍了,就不细说了。


2.2 EthernetService

  该源码的路径为frameworks/base/services/java/com/android/server/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() {//这个会在2.1章节的startService中调用到
        Log.i(TAG, "Registering service " + Context.ETHERNET_SERVICE);
        publishBinderService(Context.ETHERNET_SERVICE, mImpl);
    }

    @Override
    public void onBootPhase(int phase) {//onBootPhase()可以在boot的各个阶段被调用。在EthernetService中,当系统处于PHASE_SYSTEM_SERVICES_READY阶段时,会调用EthernetServiceImpl.start()方法,做一些Ethernet的初始化工作
        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
            mImpl.start();//启动EthernetServiceImpl服务
        }
    }
}

-在EthernetService的构造函数中创建一个EthernetServiceImpl对象,它是EthernetManager的Binde服务端。再调用EthernetService的onStart()方法后,会将该服务注册到ServiceManager中以供客户端使用。至此用户可以通过对外暴露的EthernetManager接口使用以太网相关的服务了,而这里的EthernetServiceImpl又像EthernetManager提供服务,并且最终EthernetServiceImpl又讲相关的事务委托给EthernetNetworkFactory来包揽所有的以太网网络管理操作。

-onBootPhase()可以在boot的各个阶段被调用。在EthernetService中,当系统处于PHASE_SYSTEM_SERVICES_READY阶段时,会调用EthernetServiceImpl.start()方法,做一些Ethernet的初始化工作,此处即启动EthernetServiceImpl服务


2.3 EthernetServiceImpl

  该源码的路径为frameworks/base/services/java/com/android/server/EthernetServiceImpl.java,其逻辑可以细分为两部分如下所示:

2.3.1 EthernetServiceImpl.EthernetServiceImpl

public class EthernetServiceImpl extends IEthernetManager.Stub {		
		//EthernetServiceImpl默认构造函数
	    public EthernetServiceImpl(Context context) {
        mContext = context;
        Log.i(TAG, "Creating EthernetConfigStore");
        mEthernetConfigStore = new EthernetConfigStore();//以太网配置信息存储类
        mIpConfiguration = mEthernetConfigStore.readIpAndProxyConfigurations();//从/misc/ethernet/ipconfig.txt读取以太网默认配置信息

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

        mTracker = new EthernetNetworkFactory(mListeners);//创建EthernetNetworkFactory以太网网络链接的管理类
    }
}

  该构造方法比较简单,其主要执行了如下逻辑:

  • 创建EthernetConfigStore对象mEthernetConfigStore ,并调用其readIpAndProxyConfigurations方法从/misc/ethernet/ipconfig.txt读取以太网默认配置信息,譬如DNS,网管信息,代理信息等

  • 创建EthernetNetworkFactoryEthernetNetworkFactory以太网网络链接的管理类对象mTracker,该对象在以太网服务中扮演着非常重要的角色。

2.3.2 EthernetServiceImpl.start

public class EthernetServiceImpl extends IEthernetManager.Stub {
		
    public void start() {
        Log.i(TAG, "Starting Ethernet service");

        HandlerThread handlerThread = new HandlerThread("EthernetServiceThread");//创建HandlerThread对象
        handlerThread.start();
        mHandler = new Handler(handlerThread.getLooper());

        mTracker.start(mContext, mHandler);//将Handler对象通过start方法传入到EthernetNetworkFactory中

        mStarted.set(true);
    }
}

  该方法比较简单,其主要执行了如下逻辑:

  • 创建HandlerThread对象handlerThread并启动,并且同时以handlerThread对象构造mHandler对象
  • 将Handler对象通过start方法传入到EthernetNetworkFactory中

  这里有一个知识点,就是假如想保存上次以太网的状态,即保存上次关机前以太网的开启或者关闭的状态,可以在start这里做一个判断(前提是每次开启和关闭以太网将状态持久化保存,可以使用persist属性),大致逻辑如下所示

public class EthernetServiceImpl extends IEthernetManager.Stub {
	public void start() {
	    mCM = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
	    HandlerThread handlerThread = new HandlerThread("EthernetServiceThread");
	    handlerThread.start();
	    mHandler = new Handler(handlerThread.getLooper());
	    mEnabled = getPersistedState();//获取持久化状态
	    Log.i(TAG, "Ethernet Persisted Enabled " + mEnabled);
	    setState(mEnabled);  
	  }
		
	  //根据持久化状态,判断是否要开启以太网服务
	  public synchronized void setState(int state) {
	    enforceChangePermission();
	    Log.i(TAG, "setState from mState=" + mState + " to state=" + state);
	    if (mState != state) {
	      mState = state;
	      if (state == EthernetManager.ETHERNET_STATE_DISABLED) {
	        setPersistedState(EthernetManager.ETHERNET_STATE_DISABLED);
	        mTracker.stopInterface();
	        mStarted.set(false);
	      } else {
	        setPersistedState(EthernetManager.ETHERNET_STATE_ENABLED);
	        mTracker.stop();
	        mTracker.start(mContext, mHandler);
	        mStarted.set(true);
	      }
	    }
	  }
}

  至此以太网服务已经在ServiceManager中注册成功了,用户可以通过EthernetManager来操作以太网相关的服务了。在后面的篇章中我们将会接着继续分析以太网的框架,希望大伙能感兴趣。



小结

  本来打算是将所有的以太网的框架放在一个章节里面讲透彻,但是发现涉及的内容实在是太多了,所以决定做成一个系列的篇章,尽力的做到将每个知识点分析透彻。

本文地址:https://blog.csdn.net/tkwxty/article/details/107209641

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网