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

原创 2017年07月17日 19:55:15

5 setPreferredNetworkType详解

5.1 RIL处理

RIL.java中setPreferredNetworkType方法如下,

@Override
public void setPreferredNetworkType(int networkType , Message response) {
      RILRequest rr = RILRequest.obtain(
          RILConstants.RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, response);
rr.mParcel.writeInt(1);
      rr.mParcel.writeInt(networkType);
mPreferredNetworkType = networkType;
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                + " : " + networkType);
send(rr);
}

发送的是RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE类型的消息。

 

每一个通过RIL发送的消息都会有对应的返回消息,RIL中的processSolicited方法会对

RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE类型的消息处理如下,

A,首先获取ril库上报的数据,

case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: ret =  responseVoid(p); break;

responseVoid方法返回的是null,

B,然后进行回调,

if (rr.mResult != null) {
      AsyncResult.forMessage(rr.mResult, ret, null);
      rr.mResult.sendToTarget();
}

AsyncResult 回调就一个原则,谁发起谁处理。

回看MobileNetworkSettings的onPreferenceChange方法,

mPhone.setPreferredNetworkType(modemNetworkMode, mHandler
    .obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE));

调用PhoneProxy的setPreferredNetworkType携带的是MESSAGE_SET_PREFERRED_NETWORK_TYPE消息,

因此AsyncResult 回调到MobileNetworkSettings, MobileNetworkSettings中对MESSAGE_SET_PREFERRED_NETWORK_TYPE

消息处理如下,

case MESSAGE_SET_PREFERRED_NETWORK_TYPE:
      handleSetPreferredNetworkTypeResponse(msg);
    break;

handleSetPreferredNetworkTypeResponse方法如下,

private void handleSetPreferredNetworkTypeResponse(Message msg) {
   AsyncResult ar = (AsyncResult) msg.obj;
   final int phoneSubId = mPhone.getSubId();
if (ar.exception == null) {
          int networkMode = Integer.valueOf(
               mButtonPreferredNetworkMode.getValue()).intValue();
         android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
          android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
                        networkMode );
         networkMode = Integer.valueOf(mButtonEnabledNetworks.getValue()).intValue();
         android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
          android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
                        networkMode );
      } else { 
mPhone.getPreferredNetworkType(obtainMessage(
MESSAGE_GET_PREFERRED_NETWORK_TYPE));
      }
}

A,如果ril库对RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE 消息处理没有出现异常,则再次将网络模式

写入到数据库中保存起来。

B,否则接着调用PhoneProxy的getPreferredNetworkType方法获取当前的网络模式。这个方法的调用流程和

setPreferredNetworkType方法调用流程完全一样,在此就不赘述了。

其实模式切换比打开还要复杂,首先会断开原来的连接,然后重新发起拨号,最后拨号完成。

5.2 RIL_UNSOL_DATA_CALL_LIST_CHANGED

一般情况下,打开数据网络并且设置网络模式之后,就可以正常的拨号上网了.一般的各大国内厂商的手机也都可以上网,

因为基于高通解决方案的reference-ril库比较稳定.但是一些模块厂商的reference-ril库很不稳定,存在或多或少的问题

导致模式切换的时候无法上网。一般情况下,有以下2种情况导致数据业务连接失败:

1, Modem未上报RIL_UNSOL_DATA_CALL_LIST_CHANGED消息,或者上报包含错误码或者链接中断;

2, 数据网络模式切换时,查询 RIL_REQUEST_DATA_REGISTRATION_STATE消息出错;

一般地,在模式切换时,中间会断开并且重新连接一次,而负责重新连接的就是根据modem上报的

RIL_UNSOL_DATA_CALL_LIST_CHANGED消息,RIL.java对的processUnsolicited方法该消息的处理如下,

首先获取并解析底层ril上传的数据,

case RIL_UNSOL_DATA_CALL_LIST_CHANGED: ret = responseDataCallList(p);break;

responseDataCallList方法如下,

private Object
    responseDataCallList(Parcel p) {
        ArrayList<DataCallResponse> response;
        int ver = p.readInt();
        int num = p.readInt();//读取socket数据
        riljLog("responseDataCallList ver=" + ver + " num=" + num);
        response = new ArrayList<DataCallResponse>(num);
        for (int i = 0; i < num; i++) {
            response.add(getDataCallResponse(p, ver));//解析
        }
        return response;
    }

解析完数据之后,将数据发送出去,进行回调.

case RIL_UNSOL_DATA_CALL_LIST_CHANGED:
    if (RILJ_LOGD) unsljLogRet(response, ret);
mDataNetworkStateRegistrants.notifyRegistrants(new AsyncResult(null, ret, null));
break;

RIL.java中的消息都是谁注册谁处理, mDataNetworkStateRegistrants是谁注册的呢?

RIL的父类BaseCommands中, registerForDataNetworkStateChanged方法如下,

@Override
public void registerForDataNetworkStateChanged(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
mDataNetworkStateRegistrants.add(r);
}

DcController的内部类DccDefaultState调用registerForDataNetworkStateChanged方法进行注册的,

DccDefaultState是一个状态机,刚开始进入该状态时就会注册,

public void enter() {
   mPhone.mCi.registerForRilConnected(getHandler(),
                    DataConnection.EVENT_RIL_CONNECTED, null);
   mPhone.mCi.registerForDataNetworkStateChanged(getHandler(),
                    DataConnection.EVENT_DATA_STATE_CHANGED, null);
   if (Build.IS_DEBUGGABLE) {
         mDcTesterDeactivateAll =
                new DcTesterDeactivateAll(mPhone, DcController.this, getHandler());
    }
}

注册时handler类型是EVENT_DATA_STATE_CHANGED,因此, mDataNetworkStateRegistrants.notifyRegistrants(newAsyncResult(null, ret, null)) 

这句回调的是DccDefaultState的processMessage方法,有关EVENT_DATA_STATE_CHANGED消息处理的代码如下,

case DataConnection.EVENT_DATA_STATE_CHANGED:
      ar = (AsyncResult)msg.obj;
      if (ar.exception == null) {
          onDataStateChanged((ArrayList<DataCallResponse>)ar.result);
      } else {
           log("DccDefaultState: EVENT_DATA_STATE_CHANGED:" +
                                    " exception; likely radio not available, ignore");
      }
    break;

在onDataStateChanged方法中,首先读取上报的数据,然后根据状态做不同的处理.

一般数据网络模式切换时候出现问题大部分都是因为RIL_UNSOL_DATA_CALL_LIST_CHANGED消息,具体的问题可以

分析onDataStateChanged方法,该方法会打出大量的log。

RIL上报RIL_UNSOL_DATA_CALL_LIST_CHANGED消息时,一般会有2种结果,

1,网络从连接的状态转到断开状态;

2,网络从断开状态转到连接状态。

5.2.1 转到断开状态

如果当前状态是连接状态,在onDataStateChanged中关键代码如下,

for (DataConnection dc : dcsToRetry) {
     dc.sendMessage(DataConnection.EVENT_LOST_CONNECTION, dc.mTag);
}

然后DataConnection中的DcActiveState状态的processMessage方法就会处理EVENT_LOST_CONNECTION消息,

case EVENT_LOST_CONNECTION: {
    •••
    if (mRetryManager.isRetryNeeded()) {
         •••
        mDcRetryAlarmController.startRetryAlarm(EVENT_RETRY_CONNECTION, mTag,
                                delayMillis);
        transitionTo(mRetryingState);
    }
•••

跳转到DcRetryingState状态,就像在第三章中论述的那样,无论DcActiveState跳到哪种状态,最后都会调用exit方法进而

调用NetworkAgent的sendNetworkInfo方法更新网络状态。

如果是正常断开的话,DcRetryingState状态会立即转为DcInactiveState状态,

DcRetryingState的enter方法中对应的代码如下,

mInactiveState.setEnterNotificationParams(DcFailCause.LOST_CONNECTION);
transitionTo(mInactiveState);

5.2.2 转到连接状态

从DcInactiveState状态一直转换到DcActiveState状态的过程详见第2.3小节。

版权声明:本文为博主原创文章,未经博主允许不得转载。

Android5.1网络切换策略分析

最近在在5.1移植了以太网过来,移植的过程并没有什么大问题,修改了框架上的代以及添加了Settings代码,以太网调试就基本完工了,后面只是修改下布局即可。 但是调试网络切换的时候出现了大问题。WIF...
  • Fighting4344
  • Fighting4344
  • 2015年10月14日 18:55
  • 4382

Android 多用户模式原理和实现介绍

我们可以感受到,在Android 4.2中的一个比较显著的改变就是加入了多用户的支持。因多用户手机专利早已被Symbian雇员注册,故 android官方的多用户切换目前仅支持平板设备。 多用户...
  • u011467537
  • u011467537
  • 2015年01月21日 10:14
  • 4067

分布式双活数据中心部署模式

中国IDC圈7月26日报道: 传统主备模式是一个业务只在一个数据中心运行,企业结合灾备等级需求和业务需求,在备份中心部署了大量的备份服务器,但备份中心仅为该业务提供灾备服务,只有当灾难发生、生产数据中...
  • xuyaoqiaoyaoge
  • xuyaoqiaoyaoge
  • 2015年09月22日 23:10
  • 2594

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 数据业务框架分析<四>

此部分内容是数据连接Frameworks层代码框架流程,承接Android 数据业务框架分析、都调用到TelephonyManager类的setDataEnable() 方法。 /framework...
  • hongkang218
  • hongkang218
  • 2016年11月21日 16:16
  • 255

【Android 数据业务解析】PreferredApn修改的源码分析

DcTracker中需要去获取preferredapn的id以及修改preferredapn的id,涉及到两个方法的使用,如下: getPreferredApn方法 // 得到prefer...
  • For_Forever
  • For_Forever
  • 2017年07月16日 12:23
  • 422
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:android 系统数据业务---模式切换分析(上)
举报原因:
原因补充:

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