ConnectivityManager and ConnectivityService --- Telephony data Part III

ConnectivityManager and ConnectivityService

ConnectivityManager 和ConnectivityService的作用主要有五点:
1. 监听网络连接(WiFi, GPRS, UMTS等)。

  通过NetworkAgent监听网络连接的变化。NetworkAgent是bearer和ConnectivityService沟通的桥梁,
  bearer通过NetworkAgent将网络信息更新到ConnectivityService中; ConnectivityService通过
  NetworkAgent给bearer发送一些控制类的消息等。

2. 当网络连接发生变化时发送广播通知监听者。

发送的广播主要是ConnectivityManager.CONNECTIVITY_ACTION:android.net.conn.CONNECTIVITY_CHANGE

3. 当一个网络的连接断开时,尝试打开另外一个网络连接。

当NetworkAgent断开/去注册的时候,会rematch network 和 network request,新的network会建立。

4. 为应用程序查询可用网络状态提供API,其中包括反馈详细(fine-granted)/粗略(coarse-granted)信息的API。

反馈信息最详细(fine-granted)的API是getAllNetworkState,而getAllNetworks,getActiveNetwork
相比较算是反馈信息比较粗略的API。

5. 为需要数据业务的应用程序提供请求和选择网络的API。

供应用程序请求网络连接的API是requestNetwork(...)系列,针对不同的应用需求,同名方法有六个。

NetworkFactory

每个bearer(cellular, wifi等)都会创建NetworkFactory用来接收ConnectivityService发出来的”scored NetworkRequests”, 所以NetworkFactory会有很多,比如TelephonyNetworkFactory, WifiNetworkFactory和PhoneSwitcher.PhoneSwitcherNetworkRequestListener等。

NetworkAgent

NetworkAgent是bearer(cellular,wifi)和ConnectivityService通信的通道,所以会有很多的NetworkAgent,DataConnection.DcNetworkAgent和WifiStateMachine.WifiNetworkAgent等, NetworkAgent是和network对应的,所以如果一个bearer可以同时支持不同的network((IMS / Internet / MMS Apns on cellular, or perhaps connections with different SSID or P2P for Wi-Fi),那么它可以拥有多个NetworkAgent。作为通信通道,只有那些成功建立通道的NetworkAgent才会在ConnectivityService中保存,那些断开了通道的NetworkAgent会从ConnectivityService中删掉。

下面说说cellular相关的NetworkFactory:

和Cellular相关的NetworkFactory有两个 PhoneSwitcher.PhoneSwitcherNetworkRequestListener和TelephonyNetworkFactory(数量与slot/SIM 数量一致)。PhoneSwitcher构造了内部类PhoneSwitcherNetworkRequestListener(NetworkFactory子类)对象,并使用该对象在ConnectivityService中注册了监听,所以当ConnectivityService有网络请求(request/release)的时候PhoneSwitcher会收到消息。PhoneSwitcher在内部有个ArrayList类型的变量mPrioritizedDcRequests用来存储请求信息,新请求会添加到mPrioritizedDcRequests,release的请求会从mPrioritizedDcRequests中删除。PhoneSwitcher收到请求变化的消息后会调用PhoneSwitcher.onEvaluate方法来判断哪个phone需要active,哪个phone需要deactive, 并调用Ril.setDataAllowed方法通知modem,以及将新状态通知到TelephonyNetworkFactory。
PhoneSwitcher.onEvaluate方法是如何来判断哪个phone需要active/deactive的?PhoneSwitcher.onEvaluate会调用PhoneSwitcher.phoneIdForRequest方法对mPrioritizedDcRequests中的数据进行处理,mPrioritizedDcRequests中保存的是DcRequest对象,后者包含了NetworkRequest对象,NetworkRequest中又包含了NetworkCapabilities对象,NetworkCapabilities中包含了StringNetworkSpecifier,StringNetworkSpecifier中包含了sub Id 数据,根据sub Id数据可以获取对于的Phone Id; 如果没有这些数据,那么就使用默认数据SIM对应的Phone。

综上,PhoneSwitcher会负责active/deactive 对应phone的数据功能。TelephonyNetworkFactory也在ConnectivityService中注册了监听,但是和PhoneSwitcher的作用不同,TelephonyNetworkFactory负责根据满足条件的request去调用DcTracker.requestNetwork启动切换/apn,并创建data connection。
PhoneSwitcher和TelephonyNetworkFactory都监听了Subscription change和default data subscription change的事件:

PhoneSwitcher:

        try {
            tr.addOnSubscriptionsChangedListener("PhoneSwitcher", mSubscriptionsChangedListener);
        } catch (RemoteException e) {
        }

        mContext.registerReceiver(mDefaultDataChangedReceiver,
                new IntentFilter(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED));

TelephonyNetworkFactory:

        mSubscriptionMonitor.registerForSubscriptionChanged(mPhoneId, mInternalHandler,
                EVENT_SUBSCRIPTION_CHANGED, null);

        mIsDefault = false;
        mSubscriptionMonitor.registerForDefaultDataSubscriptionChanged(mPhoneId, mInternalHandler,
                EVENT_DEFAULT_SUBSCRIPTION_CHANGED, null);

当PhoneSwitcher收到消息后会去deactive/active相应的phone的数据功能;TelephonyNetworkFactory会去release/request 数据连接。

PhoneSwitcher.PhoneSwitcherNetworkRequestListener和TelephonyNetworkFactory在向ConnectivityService注册监听之前都设置了各自的capability filter和score filter。它们的capability filter是一样的,如下:

        NetworkCapabilities netCap = new NetworkCapabilities();
        netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL);
        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_FOTA);
        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_CBS);
        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_IA);
        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_RCS);
        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_XCAP);
        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS);
        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);

TelephonyNetworkFactory的score filter是50; 而PhoneSwitcher.PhoneSwitcherNetworkRequestListener要收到所有的request,所以score filter是101。只有新request满足了capability filter和score filter后,它们才会做处理。除了使用capability和score过滤request外还可以使用重写(overridden)函数的方式,比如重写startNetwork/stopNetwork,addNetworkRequest/removeNetworkRequest。


下面说说开机初始化过程中发生的小故事:

这部分主要讲在开机初始化过程中,data connection建立之前,ConnectivityService、PhoneSwitcher以及TelephonyNetworkFactory之间代码流程,下方是一个流程图:
ConnectivityManager and ConnectivityService --- Telephony data Part III_第1张图片
首先ConnectivityService的构造函数会创建一个默认的NetworkRequest对象(mDefaultRequest)。
PhoneSwitcher创建时会构造一个PhoneSwitcherNetworkRequestListener对象(NetworkFactory子类),然后用该对象在ConnectivityService中注册监听。ConnectivityService注册监听成功并通信成功之后便会发送CMD_REQUEST_NETWORK(使用mDefaultRequest)消息,经过一系列调用之后PhoneSwitcherNetworkRequestListener.needNetworkFor方法会被调用,该方法会发送一个EVENT_REQUEST_NETWORK,然后PhoneSwitcher.onRequestNetwork方法,PhoneSwitcher.onEvaluate和PhoneSwitcher.active方法相继被调用。
TelephonyNetworkFactory的构造函数里会调用PhoneSwitcher.registerForActivePhoneSwitch方法注册监听,PhoneSwitcher.active方法就会通知TelephonyNetworkFactory; TelephonyNetworkFactory注册监听时用的是EVENT_ACTIVE_PHONE_SWITCH,收到该消息时被调用的方法是TelephonyNetworkFactory.onActivePhoneSwitch,经过流程图中的一系列方法调用,适合network request的ApnContext会被设置成Enable状态,这样当需要的时候这个ApnContext便可以用于建立data connection。

TelephonyNetworkFactory能否调用DcTracker.requestNetwork去请求连接,要取决于PhoneSwitcher是否已经通过PhoneSwitcher.active方法通知了TelephonyNetworkFactory它所对应的卡可以连接网络。
对于单卡,这部分可能不重要; 但是对于双卡,而新的网络连接请求所用的卡和当前数据卡不一致时,这部分逻辑完成 了对卡的选择。

发彩信过程中使用mms APN的流程
发彩信需要使用MMS APN,MmsNetworkManager.acquireNetwork会调用ConnectivityManager.requesetNetwork方法请求网络连接,后面的流程和上面流程图展示的很相似; network request会发送到TelephonyNetworkFactory中,TelephonyNetworkFactory会调用DcTracker.requestNetwork, 在这个方法中选择合适的ApnContext(MMS),然后开始建立网络连接。
IMS apn是怎么使用的?
IMS模块通过ConnectivityManger.requestNetwork(…)方法请求使用IMS apn建立data connection。


ConnectivityService是怎么计算score的?
当有新的network requeset注册或者NetworkAgent发生变化(注册/去注册、score发生变化、NetworkCapabilities改变和调用setAcceptUnvalidated/setAvoidUnvalidated设置针对unvalidated network的操作)时,rematchAllNetworksAndRequests/rematchNetworkAndRequests会被调用,一些network request会有新的score,而一些network可能会被断开。

  1. 当有新的network requeset注册时,对应的方法是handleRegisterNetworkRequest。
  2. 当有新的NetworkAgent注册时,对应的方法是handleRegisterNetworkRequest。
  3. 当NetworkAgent去注册时,对应的方法是handleAsyncChannelDisconnected。
  4. 当NetworkAgent的score发生变化时,对应的方法是updateNetworkScore。
  5. 当NetworkAgent的NetworkCapabilities发生变化时,对应的方法是updateCapabilities。
  6. 当setAcceptUnvalidated/setAvoidUnvalidated被调用,设置针对unvalidated network的操作时; 对应的方法是handleSetAcceptUnvalidated/handleSetAvoidUnvalidated。

rematchNetworkAndRequests(NetworkAgentInfo newNetwork, …)方法会遍历所有的request判断参数network是否是某个request的最合适的network,如果是,那么将network的score更新request的score值,并通知NetworkFactory,NetworkFactory会根据score进行操作(release/request network)。
WiFi连接/断开时,会有对应的NetworkAgent注册/去注册以及score更新,所有注册的NetworkFactory都会收到消息,TelephonyNetworkFactory收到消息后会release当前的mobile network(cellular)。


结束!

你可能感兴趣的:(ConnectivityManager and ConnectivityService --- Telephony data Part III)