Android以太网框架情景分析之启动简介
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深入剖析。
小结
本来打算是将所有的以太网的框架放在一个章节里面讲透彻,但是发现涉及的内容实在是太多了,所以决定做成一个系列的篇章,尽力的做到将每个知识点分析透彻。
更多相关文章
- Nginx系列教程(六)| 手把手教你搭建 LNMP 架构并部署天空网络电影
- 网络传输数据解析(SAX)
- Android网络图片请求+二级缓存实现
- android并发网络请求的处理
- Android每周一轮子:OkHttp(1)
- Android网络编程之通过Post传递参数
- 简单android联网
- Android(安卓)获取当前网速质量调整网络请求
- Android原生网络库HttpURLConnection分析——HTTPS部分