Data Connect流程分析(基于1.5源码)
Android的数据连接是基于PPP方式的,主要步骤为:首先通过AT命令激活PDP连接,然后利用pppd通过数据端口完成拨号连接;
数据连接的核心控制类是DataConnectionTracker,存在于GSMPhone里,数据连接不需要用户的干预,在APN设置好之后,在适当 的情况下就会自动激活,激活的入口点是:DataConnectionTracker.trySetupData→setupData→ PdpConnection.connetc→CommandsInterface.setupDefaultPDP,通过PdpConnection访 问GSMPhone中的RIL层的setupDefaultPDP实现,setupDefaultPDP的结果由 EVENT_SETUP_PDP_DONE返回,如果成功,则开始调用pppd完成实际连接,这是通过DataLink.connect实现的;
DataLink只是抽象基类,此处它的实现类是PppLink,实现DataLinkInterface接口,所以DataLink.connect实 际上调用PppLink.connect,它通过SystemService.start(SERVICE_PPPD_GPRS)开始pppd服务,并通 过checkPPP函数访问Linux的sys文件系统来查询pppd的连接状态,如果成功,便可以将LINKUP的消息通知出去以完成连接流程。
接入点使用在我看来主要包括接入点 的创建、接入点的切换以及接入点的删除三个方面,我们下面按照android 源码,按照程序调用的先后顺序依次分析其流程;
Android 因为是以事件驱动的,因此在诸如接入点设置这样的操作的时候,都是从按键触发事件开始的:Activity.java 里的onKeyDown 函数;由于是基于EVENT 驱动的,因此在每一个动作的时候都会触发一定Type 的Message ,因此对于源代码流程的分析也比较有利;
Create New APN 的过程主要就是APN 如name 、port 、proxy 等的添加以及在设置的过程里状态的切换等;
一、下面为这个过程里JAVA Framework 调用的过程:
1 、 ActivityManagerService.java:startActivity :
说明:界面跳转,使用隐式的界面跳转,这个过程是基于事件的,在Android 中,传递数据使用Intent ,Intent 相当于各个Activity 之间的桥梁,可以传递数据,可以通过Intent 启动另外一个Activity 。Intent 有显式和隐式之分,显式的是直接什么要启动的组件,比如Service 或者Activity ,隐式的通过配置的datatype 、url 、action 来找到匹配的组件启动。
2 、telephony/TelephonyProvider.java :insert 函数:
说明:通过对URL 的s_urlMatcher.match ,URL_TELEPHONY 宏的处理,对Name ,APN 等的检查和容错
3 、MobileDataStateTracker.java :MobileDataStateReceiver 函数
说明:这个是这部分处理的一个核心函数,该函数的一个实现为onReceive (),在此函数里对于APN 的各种参数如Type (isApnTypeIncluded(apnTypeList) )以及状态state 进行判断和转换,在这个时候,状态的切换为:old =CONNECTED and new state=DISCONNECTED
4 、ConnectivityService.java :handleMessage ()函数
说明:由于系统本身就是事件驱动的,因此这个handleMessage 被调用来完成network state 状态的改变:DISCONNECTED/DISCONNECTED ,并且在这个函数实现了WIFI 接入点有关判断;
5 、GpsLocationProvider.java:updateNetworkState 函数
说明:GPS 状态的更新
6 、MobileDataStateTracker.java :MobileDataStateReceiver ()函数:
说明:类似(3 ),只是状态切换变为:state= CONNECTING, old= DISCONNECTED, reason= apnChanged
7 、NetworkStateTracker.java :setDetailedState ()函数
说明:该函数记录网络状态的改变,并在改变的时候发送一个notify 事件:
Message msg = mTarget.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
8 、ConnectivityService.java :handleMessage ()函数:
说明:类似(4 ),状态:CONNECTING/CONNECTING
9 、Checkin.java :updateStats 函数:
说明:update statistics in the database
10 、MobileDataStateTracker.java :MobileDataStateReceiver
说明:处理在onReceive 里,状态为:state= CONNECTED, old= CONNECTING, reason= apnChanged
11 、NetworkStateTracker.java :setDetailedState ()函数
说明:(7 ),状态:old =CONNECTING and new state=CONNECTED
12 、NetworkStateTracker.java:updateNetworkSettings 函数
说明:该函数从Network TCP buffer 读取network 设置参数,并设置网络
13 、ConnectivityService 。java :handleDnsConfigurationChange
说明:从dnsList 里读取预设的dns 通过writePidDns 设置dns
二、下面分析RIL Java 层的处理:
该部分的核心实现存在于Ril.java 以及GsmDataConnectionTracker.java 之中,Ril.java 中RIL.RILSender 负责处理命令的发送,RIL.RILReceiver 用于处理命令响应以及主动上报信息的接收;
Ril.Java 中一个命令发送的流程为:RILRequest.obtain (命令ID )→复制参数→通过Send ()函数发送EVENT_SEND →在RILSender 线程中处理EVENT_SEND →将命令写到out stream (socket );
Ril.java 响应和主动上报消息的流程为:RILReceiver 线程监视mSocket input →readMessage (读取完整响应)→processReponse →分别处理RESPONSE_UNSOLICITED (主动上报)与REPONSE_SOLICITED (命令响应)
RILD 守护进程里的Request 都是由RIL.java 发起
1 、ApnPreference.java: onCheckedChanged
说明:检查接入点切换的ID 是否合法
2 、MobileDataStateTracker.java :MobileDataStateReceiver
说明:处理在onReceive 里,状态为:state= DISCONNECTED, old= CONNECTED
3 、ConnectivityService.java :handleMessage ()函数:
说明:状态:DISCONNECTED/DISCONNECTED
4 、ActivityThread.java :getProvider
说明:ActivityThread.java 是app 里的一个实例,在main 里创建了一个thread ,在getProvider 里 holder = ActivityManagerNative.getDefault().getContentProvider(getApplicationThread(), name); 进行了判断
5 、Checkin.java :updateStats 函数:
说明:update statistics in the database ,会对PHONE_GPRS_ATTEMPTED 进行判断,在emulator 里会报Can't update stat PHONE_GPRS_ATTEMPTED: java.lang.IllegalArgumentException: Unknown URL content://android.server.checkin/stats 的错误
6 、MobileDataStateTracker.java :MobileDataStateReceiver
说明:处理在onReceive 里,state= CONNECTED, old= CONNECTING
7 、NetworkStateTracker.java :setDetailedState ()函数
说明:状态:old =CONNECTING and new state=CONNECTED
8 、ConnectivityService.java :handleMessage ()函数:
说明:状态:CONNECTED/CONNECTED
9 、NetworkStateTracker.java:updateNetworkSettings 函数
说明:该函数从Network TCP buffer 读取network 设置参数,并设置网络
10 、ConnectivityService.java :handleDnsConfigurationChange
说明:从dnsList 里读取预设的dns 通过writePidDns 设置dns