android 系统数据业务---模式切换分析(下)

原创 2017年07月17日 20:05:26

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方法如下,

@Override
public 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 网络变化流程

Step 1:注册监听事件 GsmServiceStateTracker(CdmaServiceStateTracker) 在构造函数就会通过registerForVoiceNetworkState...
  • leesino
  • leesino
  • 2016年01月25日 11:04
  • 2545

数据业务建立流程之DcTracker创建过程(原)

一、DcTracker介绍         DcTracker是Telephony框架中负责数据业务的核心(类似于GsmCallTracker是通话业务核心,GsmServiceStateT...
  • u010961631
  • u010961631
  • 2015年11月02日 16:19
  • 5717

一、Android DcTracker的创建及准备工作

DcTracker是在每个Phone构造的时候创建的,DcTrackerBase是DcTracker,他们的核心都是Handler。@GSMPhone.java public GSMPhone (...
  • xiabodan
  • xiabodan
  • 2016年12月20日 17:01
  • 1111

[Android6.0] 数据业务重试机制

解析Android telephony对数据链接错误的重试机制。
  • lcr006
  • lcr006
  • 2016年12月26日 10:45
  • 1759

android 系统数据业务---模式切换分析(上)

5 setPreferredNetworkType详解 5.1 RIL处理 RIL.java中setPreferredNetworkType方法如下, @Override public void se...
  • u012439416
  • u012439416
  • 2017年07月17日 19:55
  • 770

android 系统上做GC双模的---数据业务的处理分析

一:modem相关的各种状态的监听和通知机制/通话相关的图标变换的工作原理。网络状态,evdo,图标的处理a、注册监听部分==>SystemServer.java  init2()    Thread...
  • basonjiang_sz
  • basonjiang_sz
  • 2011年03月17日 12:38
  • 2312

android 系统数据业务---打开(下)

2.3状态转换 上一小节中,调用onConnect 方法拨号后就接着调用transitionTo方法进入了DcActivatingState状态, 当RIL收到RIL_REQUEST_SETUP_...
  • u012439416
  • u012439416
  • 2017年07月17日 19:39
  • 387

android 系统数据业务---打开

2数据业务打开 DcTracker的onTrySetupData调用流程图如下, onTrySetupData方法如下, protected boolean onTrySetupDa...
  • u012439416
  • u012439416
  • 2017年07月17日 19:19
  • 490

android系统数据业务知识点总结(一)

1.APN APN简介       APN指一种网络接入技术,是通过手机上网时必须配置的一个参数,它决定了手机通过哪种接入方式来访问网络。对于手机用户来说,可以访问的外部网络类型有很多,例如:Inte...
  • Terrence_he
  • Terrence_he
  • 2017年10月10日 16:33
  • 264

Android 数据业务框架分析<二>

Android 数据业务框架分析 一旦选中数据流量选项卡, updateBody()方法得到执行,【开启/关闭】的按钮等就呈现在界面上。  OnCheckedChang...
  • hongkang218
  • hongkang218
  • 2016年11月21日 15:26
  • 296
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:android 系统数据业务---模式切换分析(下)
举报原因:
原因补充:

(最多只允许输入30个字)