android 系统数据业务---模式切换分析(下)
来源:互联网 发布:mac matte chili 编辑:程序博客网 时间:2024/05/24 04:13
5.3 RIL_REQUEST_DATA_REGISTRATION_STATE
在GsmServiceStateTracker的构造方法中,注册了一些监听事件,
mCi.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);mCi.registerForVoiceNetworkStateChanged(this,EVENT_NETWORK_STATE_CHANGED, null);
当ril守护进程上报一些消息时,例如UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED,就会发送
EVENT_NETWORK_STATE_CHANGED消息, GsmServiceStateTracker对该消息处理如下,
case EVENT_NETWORK_STATE_CHANGED: pollState(); break;
5.3.1 消息发送
以电信卡为例,在数据网络模式切换的过程中,都会调用GsmServiceStateTracker的pollState方法获取模式切换之前的状态,
mPollingContext[0]++; mCi.getDataRegistrationState( obtainMessage(EVENT_POLL_STATE_GPRS, mPollingContext));
一会儿处理消息回调时会调用该类对EVENT_POLL_STATE_GPRS消息的处理,
RIL中的getDataRegistrationState方法如下,
@Overridepublic void getDataRegistrationState (Message result) { //消息封装 RILRequest rr = RILRequest.obtain(RIL_REQUEST_DATA_REGISTRATION_STATE, result);if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));send(rr);//通过socket向的ril发送 RIL_REQUEST_DATA_REGISTRATION_STATE }
3.3.2 消息回调处理
RIL中对RIL_REQUEST_DATA_REGISTRATION_STATE消息处理如下,
首先调用responseStrings方法获取返回的数据,
case RIL_REQUEST_DATA_REGISTRATION_STATE: ret = responseStrings(p); break;
然后回调GsmServiceStateTracker到进行处理,
if (rr.mResult != null) { AsyncResult.forMessage(rr.mResult, ret, null); rr.mResult.sendToTarget();}
GsmServiceStateTracker的handleMessage方法对EVENT_POLL_STATE_GPRS消息处理如下,
1,首先数据模式的CS/PS值,然后保存在ServiceState对象中,
states = (String[])ar.result;//获取上报的结果int type = 0;int regState = ServiceState.RIL_REG_STATE_UNKNOWN;mNewReasonDataDenied = -1;mNewMaxDataCalls = 1;if (states.length > 0) { //根据字符串组的长度解析CS/PS值,一般在长度为4 try { regState = Integer.parseInt(states[0]);//获取CS// states[3] (if present) is the current radio technology if (states.length >= 4 && states[3] != null) { //获取PS type = Integer.parseInt(states[3]); } if ((states.length >= 5 ) && (regState == ServiceState.RIL_REG_STATE_DENIED)) { mNewReasonDataDenied = Integer.parseInt(states[4]); } if (states.length >= 6) { mNewMaxDataCalls = Integer.parseInt(states[5]); } } catch (NumberFormatException ex) { loge("error parsing GprsRegistrationState: " + ex);}}// 将CS/PS值保存在ServiceState对象中int dataRegState = regCodeToServiceState(regState); mNewSS.setDataRegState(dataRegState);mDataRoaming = regCodeIsRoaming(regState);mNewSS.setRilDataRadioTechnology(type);
2,调用pollStateDone方法发起拨号上网.
pollStateDone方法中有关拨号上网的代码如下,
//对比上次和当前的网络数据模式的CS值boolean hasDataRegStateChanged =mSS.getDataRegState() != mNewSS.getDataRegState(); //对比上次和当前的网络数据模式的PS值boolean hasRilDataRadioTechnologyChanged = mSS.getRilDataRadioTechnology() != mNewSS.getRilDataRadioTechnology();if (hasDataRegStateChanged || hasRilDataRadioTechnologyChanged) { notifyDataRegStateRilRadioTechnologyChanged(); mPhone.notifyDataConnection(null); }
如果上次和当前的CS/PS值有一个不相同,则会调用notifyDataRegStateRilRadioTechnologyChanged方法,
最后调用RIL的setupDataCall方法向ril库发送RIL_REQUEST_SETUP_DATA_CALL消息进行拨号上网。
5.4 RIL_REQUEST_SETUP_DATA_CALL
上层发起拨号一般会调用RIL向ril守护进程发送RIL_REQUEST_SETUP_DATA_CALL消息。
继续上个小节, GsmServiceStateTracker的notifyDataRegStateRilRadioTechnologyChanged方法其实在父类
ServiceStateTracker中实现,如下,
protected void notifyDataRegStateRilRadioTechnologyChanged() { int rat = mSS.getRilDataRadioTechnology(); int drs = mSS.getDataRegState(); if (DBG) log("notifyDataRegStateRilRadioTechnologyChanged: drs=" + drs + " rat=" + rat); mPhoneBase.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE, ServiceState.rilRadioTechnologyToString(rat)); mDataRegStateOrRatChangedRegistrants.notifyResult(new Pair<Integer, Integer>(drs, rat));}
mDataRegStateOrRatChangedRegistrants.notifyResult这句话怎么继续调用呢?
mDataRegStateOrRatChangedRegistrants其实也是RegistrantList对象,
protected RegistrantList mDataRegStateOrRatChangedRegistrants = new RegistrantList();
关键是看谁注册,谁注册就是谁调用,注册方法如下,
public void registerForDataRegStateOrRatChanged(Handler h, int what, Object obj) { Registrant r = new Registrant(h, what, obj); mDataRegStateOrRatChangedRegistrants.add(r); notifyDataRegStateRilRadioTechnologyChanged();}
整个android系统中有2个地方调用了该方法, DcTracker.java和DataConnection.java,
首先看看DataConnection,在DataConnection的内部类DcDefaultState的enter方法中,
mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(getHandler(), DataConnection.EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED, null);
mDataRegStateOrRatChangedRegistrants.notifyResult这句话其实就是向DataConnection发送
EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED消息。
这里还有一个需要注意的点是DcDefaultState状态机是DataConnection其他所有状态机的父状态机,
但不是父类,这是有区别的,虽然功能是类似于父类。
然后看DcTracker.java,DcTracker.java的构造方法会调用update方法, update 方法调用registerForAllEvents方法,
该方法中有关注册的代码如下,
mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(this, DctConstants.EVENT_DATA_RAT_CHANGED, null);
同样的, mDataRegStateOrRatChangedRegistrants.notifyResult也向DcTracker.java发送了EVENT_DATA_RAT_CHANGED消息,
DcTracker.java的handleMessage对该消息处理如下,
case DctConstants.EVENT_DATA_RAT_CHANGED: //May new Network allow setupData, so try it here setupDataOnConnectableApns(Phone.REASON_NW_TYPE_CHANGED, RetryFailures.ONLY_ON_CHANGE);break;
setupDataOnConnectableApns处理流程详情见第二章开头,其后的过程和打开数据业务的流程完全一摸一样。将步骤再列一下,
1,创建DataConnection 和 DcAsyncChannel对象, 将2个对象通过Handler绑定,通过AsyncChannel机制进行进程间的通信。
2,向RIL发送RIL_REQUEST_SETUP_DATA_CALL消息,进行拨号
3,完成状态从DcInactiveState 到 DcActivatingState 最后到 DcActiveState的转变
4,构造ConnectivityService 对象,注册。ConnectivityService将通过AsyncChannel与phone进程的NetworkAgent进行跨进程通信。
5,通过NetworkManagementService和netd守护进程进行交互,完成完成网络属性的添加,这样才算完成了拨号上网。
并且,每一次数据网络的切换,ril库会上报RIL_UNSOL_DATA_CALL_LIST_CHANGED消息,没有上报或者上报的数据不对肯定是无法上网的;
每一次数据网络的切换,AP测会主动查询注册状态,ril库会返回RIL_REQUEST_DATA_REGISTRATION_STATE信息以及数据网络的注册状态,
返回的信息时一个数组,比较重要的是第一个和第四个,如果这2个值有问题,就无法进行拨号上网。
小结:
其实,数据业务的切换包括了数据业务关闭和打开,和ril守护进程交互的流程如下,
1,phone进程发送RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE消息到ril守护进程。
2,ril守护进程首先断开网络,上报RIL_UNSOL_DATA_CALL_LIST_CHANGED消息。
3,phone进程更新NetworkAgent 网络状态,和netd守护进程交互。
4, ril守护进程上报大量消息,例如UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED消息等。
5,phone进程发送RIL_REQUEST_DATA_REGISTRATION_STATE消息查询网络注册状态。
6, phone进程根据ril守护进程回应的RIL_REQUEST_DATA_REGISTRATION_STATE消息向ril守护进程发送RIL_REQUEST_SETUP_DATA_CALL消息发起拨号。
7,phone进程会收到RIL_UNSOL_DATA_CALL_LIST_CHANGED消息更新状态等。
- android 系统数据业务---模式切换分析(下)
- android 系统数据业务---模式切换分析(上)
- android 系统数据业务---模式
- android 系统数据业务---模式
- android 系统数据业务---打开(下)
- android 系统数据业务---打开
- android 系统数据业务---关闭
- Android 数据业务框架分析<一>
- Android 数据业务框架分析<三>
- android 系统上做GC双模的---数据业务的处理分析
- android 系统上做GC双模的---数据业务的处理分析
- android 系统数据业务---phone进程启动
- android 系统数据业务---打开/关闭概述
- android系统数据业务知识点总结(一)
- android系统数据业务知识点总结(二)
- 【Android 数据业务解析】PreferredApn修改的源码分析
- 数据业务支撑系统
- Android 切换系统语言源码分析
- XML基础知识及四种解析方法
- 如何挖掘长尾词,长尾关键词挖掘方法大全
- LintCode_632_二叉树的最大结点
- 选择器 伪类伪元素
- linux命令---top
- android 系统数据业务---模式切换分析(下)
- 进程保活-双进程守护的正确姿势
- 金融衍生品介绍
- 利用指针对数组&句子进行逆序
- Apache ActiveMQ 各个版本所依赖的JDK版本
- HDU5692:Snacks(DFS序 & 线段树区间更新)
- 计算机网络 --应用层
- 通过浏览器获得百度云盘大文件真实下载地址
- POJ 1905 Expanding Rods(二分)