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.javaframeworks/base/core/java/android/net/---ConnectivityManager.java---EthernetManager.java---IConnectivityManager.aidl---IEthernetManager.aidl---LinkProperties.java---NetworkPolicy.java---NetworkAgent.java---NetworkFactory.java---NetworkInfo.java---ProxyInfo.javaframeworks/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来操作以太网相关的服务了。在后面的篇章中我们将会接着继续分析以太网的框架,希望大伙能感兴趣。关于后续EthernetNetworkFactory章节移步至博客Android以太网框架情景分析之EthernetNetworkFactory深入剖析



小结

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

更多相关文章

  1. Nginx系列教程(六)| 手把手教你搭建 LNMP 架构并部署天空网络电影
  2. 网络传输数据解析(SAX)
  3. Android网络图片请求+二级缓存实现
  4. android并发网络请求的处理
  5. Android每周一轮子:OkHttp(1)
  6. Android网络编程之通过Post传递参数
  7. 简单android联网
  8. Android(安卓)获取当前网速质量调整网络请求
  9. Android原生网络库HttpURLConnection分析——HTTPS部分

随机推荐

  1. Android中LogCat工具的使用
  2. Android生成apk后防反编译
  3. android中,用SimpleAdapter创建有自己布局
  4. 4.28 context.getExternalFilesDir(null)
  5. Android怎么用onCreateOptionsMenu()创建
  6. Android生成签名文件并用其对apk文件进行
  7. 使用ndk开发android 5.0 平台错误处理(1)
  8. Android4.1输入子系统框架介绍和性能分析
  9. android 真机 安装 模拟器 DevTools Deve
  10. USB设备驱动程序学习笔记(一)