android 系统数据业务---打开(下)
来源:互联网 发布:unity3d 动画循环播放 编辑:程序博客网 时间:2024/05/16 09:16
2.3状态转换
上一小节中,调用onConnect 方法拨号后就接着调用transitionTo方法进入了DcActivatingState状态,
当RIL收到RIL_REQUEST_SETUP_DATA_CALL消息时, 将向DataConnection发送
EVENT_SETUP_DATA_CONNECTION_DONE的消息. DcActivatingState的processMessage方法
处理EVENT_SETUP_DATA_CONNECTION_DONE消息主要逻辑如下,
首先调用onSetupConnectionCompleted解析拨号结果,
ar = (AsyncResult) msg.obj;cp = (ConnectionParams) ar.userObj;DataCallResponse.SetupResult result = onSetupConnectionCompleted(ar);
然后根据拨号结果分别进行处理,
switch (result) { case SUCCESS: // All is well mDcFailCause = DcFailCause.NONE; transitionTo(mActiveState); break; case ERR_BadCommand: ••• mInactiveState.setEnterNotificationParams(cp, result.mFailCause); transitionTo(mInactiveState); break;•••
如果拨号成功就进入DcActiveState状态,
如果拨号过程中出现问题就进入DcInactiveState状态。
到此,和RIL交互已经告一段落了。接着看phone进程的处理。
直接分析正常的情况, DcActiveState状态。
DcActiveState进入时会调用enter方法, DcActiveState实现了自己的enter方法,如下,
首先通知其它APK,例如SystemUI,拨号成功。SystemUI会刷新界面的一些状态信息等等。
notifyAllOfConnected(Phone.REASON_CONNECTED);
当然,将信息传递给apk,一般有2种方法,
将相关信息通过广播发送出去,apk一般注册广播就可以了;
另外一种是通过回调接口,apk注册回调,直接监听状态就可以了。
但是对于phone信息,还可以通过TelephonyManager接口主动查询。
因此如何通知在此就不论述了。
然后更新DcNetworkAgent对象,通过DcNetworkAgent配置路由等,让终端可以真正的访问网络。对应的代码如下,
mNetworkAgent = new DcNetworkAgent(getHandler().getLooper(), mPhone.getContext(), "DcNetworkAgent", mNetworkInfo, makeNetworkCapabilities(), mLinkProperties, 50, misc);
2.4ConnectivityService管理网络
DcNetworkAgent是DataConnection的内部类,继承NetworkAgent。NetworkAgent又继承Handler,
DcNetworkAgent的构造方法直接调用父类NetworkAgent的构造方法, NetworkAgent的构造方法如下,
public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni, NetworkCapabilities nc, LinkProperties lp, int score, NetworkMisc misc) { super(looper); LOG_TAG = logTag; mContext = context; if (ni == null || nc == null || lp == null) { throw new IllegalArgumentException(); }if (VDBG) log("Registering NetworkAgent"); ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService( Context.CONNECTIVITY_SERVICE); cm.registerNetworkAgent(new Messenger(this), new NetworkInfo(ni), new LinkProperties(lp), new NetworkCapabilities(nc), score, misc);}
通过ConnectivityManager将自己注册到ConnectivityService, 注意到此处的Messenger中包裹了NetworkAgent自身,
NetworkAgent继承自Handler,ConnectivityService将通过AsyncChannel与NetworkAgent进行跨进程通信。
ConnectivityManager的registerNetworkAgent方法如下,
public int registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp, NetworkCapabilities nc, int score, NetworkMisc misc) { try { return mService.registerNetworkAgent(messenger, ni, lp, nc, score, misc); } catch (RemoteException e) { return NETID_UNSET; } }
直接调用ConnectivityService的registerNetworkAgent方法进行注册。
ConnectivityService在SystemServer中构造和启动,因此属于systemserver进程,这样从phone进程到systemserver进程了,
当然这个点是通过AsyncChannel进行通信。
ConnectivityService管理android系统中所有和网络相关的,包括phone进程的数据网络,还包括wifi等等。
ConnectivityService的registerNetworkAgent调用流程图如下,
registerNetworkAgent方法如下,
//构造NetworkAgentInfo对象, 存储整个网络有关的信息NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(), new NetworkInfo(networkInfo), new LinkProperties(linkProperties), new NetworkCapabilities(networkCapabilities), currentScore, mContext, mTrackerHandler, new NetworkMisc(networkMisc), mDefaultRequest);••• //发送消息mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT, nai));
一般跨进程调用之后都会发送消息转换到主线程中执行, ConnectivityService对该消息的处理如下,
case EVENT_REGISTER_NETWORK_AGENT: { handleRegisterNetworkAgent((NetworkAgentInfo)msg.obj); break;}
handleRegisterNetworkAgent方法如下,
private void handleRegisterNetworkAgent(NetworkAgentInfo na) { if (VDBG) log("Got NetworkAgent Messenger"); mNetworkAgentInfos.put(na.messenger, na); assignNextNetId(na);//mTrackerHandler与NetworkAgent的handler绑定在一起 na.asyncChannel.connect(mContext, mTrackerHandler, na.messenger); NetworkInfo networkInfo = na.networkInfo; na.networkInfo = null; updateNetworkInfo(na, networkInfo); //更新NetworkAgentInfo中的NetworkInfo }
updateNetworkInfo方法主要逻辑如下,
首先通过binder机制调用NetworkManagementService创建网络,配置路由等网络属性,
if (networkAgent.isVPN()) { mNetd.createVirtualNetwork(networkAgent.network.netId, !networkAgent.linkProperties.getDnsServers().isEmpty(), (networkAgent.networkMisc == null || !networkAgent.networkMisc.allowBypass));} else { mNetd.createPhysicalNetwork(networkAgent.network.netId, networkAgent.networkCapabilities.hasCapability( NET_CAPABILITY_NOT_RESTRICTED) ? null : NetworkManagementService.PERMISSION_SYSTEM);}
然后调用updateLinkProperties更新网络信息等。
最后调用rematchNetworkAndRequests方法理数据拨号产生的NetworkAgent对象。
1.NetworkManagementService
NetworkManagementService和ConnectivityService一样,在SystemServer中构造和启动,因此属于systemserver进程,
并不是一个单独的进程。因此,从ConnectivityService到NetworkManagementService是进程间的binder机制调用。
NetworkManagementService的createPhysicalNetwork方法如下,
public void createPhysicalNetwork(int netId, String permission) { mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); try { if (permission != null) { mConnector.execute("network", "create", netId, permission); } else { mConnector.execute("network", "create", netId); } } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); }}
原来是调用NativeDaemonConnector类的execute方法完成。
NativeDaemonConnector是 NetworkManagementService和netd 守护进程通信的中间桥梁。
详细的机制见·····
2. updateLinkProperties方法如下,
updateLinkProperties最后都是通过NetworkManagementService,到netd守护进程完成网络属性的添加,
如果添加有问题,会直接断开网络。
注意:
ConnectivityService的updateNetworkInfo方法中有一段log很重要,
if (DBG) { log(networkAgent.name() + " EVENT_NETWORK_INFO_CHANGED, going from " + (oldInfo == null ? "null" : oldInfo.getState()) + " to " + state);}
明确地指出了当前的连接状态,比如,从
01-01 20:20:37.220 D/ConnectivityService( 459): NetworkAgentInfo [MOBILE (CDMA - EvDo rev. A) - 100] EVENT_NETWORK_INFO_CHANGED, going from null to CONNECTED
01-01 20:20:38.199 D/ConnectivityService( 459): NetworkAgentInfo [MOBILE (CDMA - EvDo rev. A) - 100] EVENT_NETWORK_INFO_CHANGED, going from CONNECTED to DISCONNECTED小结:
数据业务的打开主要分为以下几个过程:
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守护进程进行交互,完成完成网络属性的添加,这样才算完成了拨号上网。
- android 系统数据业务---打开(下)
- android 系统数据业务---打开
- android 系统数据业务---打开/关闭概述
- android 系统数据业务---模式切换分析(下)
- android 系统数据业务---关闭
- android 系统数据业务---模式
- android 系统数据业务---模式
- android 系统数据业务---phone进程启动
- android 系统数据业务---模式切换分析(上)
- android系统数据业务知识点总结(一)
- android系统数据业务知识点总结(二)
- 数据业务支撑系统
- Android数据业务发起流程
- Android N数据业务总结
- Android数据业务发起流程
- Mac系统下,打开Android SDK Manager
- Android系统下打开指定的浏览器
- Android 下Qt打开 调用系统程序打开文件
- git和github的基本使用
- 集合(容器)hoshCode算法
- Codeforces Round #382 (Div. 1) 736A Tennis Championship
- Robotframework -- Run Keyword关键字
- ionic实战项目从0开始
- android 系统数据业务---打开(下)
- 被点名批评#2
- python logging 模块(三)
- Java SWT
- 设计前端(一)
- 决策树的剪枝操作
- 数据库中的变长类型
- 在MATLAB2017a中使用mex找不到编译器的问题
- js版本的全选 反选 和全不选