android43以太网流程追踪记录Word格式文档下载.docx
《android43以太网流程追踪记录Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《android43以太网流程追踪记录Word格式文档下载.docx(32页珍藏版)》请在冰豆网上搜索。
mobile_hipri,5,0,3,60000,true"
mobile_fota,10,0,2,60000,true"
mobile_ims,11,0,2,60000,true"
mobile_cbs,12,0,2,60000,true"
wifi_p2p,13,1,0,-1,true"
/string-array>
上面各项字符串的排列顺序与类NetworkConfig的成员变量一一对应,按顺序如下:
name,type,radio,priority,restoreTime,dependencyMet
第4个元素就是我们需要的优先级设置值
1.2ConnectivityService服务
在上面的内容中,我们在配置文件中设置了不同网络类型的优先级。
那么配置文件里面的设置是在什么时候被系统读取使用的呢?
通过查看源代码会发现是在类ConnectivityService的构造函数中被调用的。
具体代码如下:
String[]naStrings=context.getResources().getStringArray(
com.android.internal.RworkAttributes);
for(StringnaString:
naStrings){
try{
NetworkConfign=newNetworkConfig(naString);
if(n.type>
ConnectivityManager.MAX_NETWORK_TYPE){
loge("
ErrorinnetworkAttributes-ignoringattempttodefinetype"
+
n.type);
continue;
}
if(mNetConfigs[n.type]!
=null){
ErrorinnetworkAttributes-ignoringattempttoredefinetype"
if((mRadioAttributes[n.radio]==null)&
&
(n.type!
=ConnectivityManager.TYPE_ETHERNET)){
ErrorinnetworkAttributes-ignoringattempttouseundefined"
"
radio"
+n.radio+"
innetworktype"
+n.type);
mNetConfigs[n.type]=n;
mNetworksDefined++;
}catch(Exceptione){
//ignoreit-leavetheentrynull
首先获取config.xml中的字符串保存在String数组naStrings中,然后循环处理数组中的每个元素(如"
)。
之前我们说过,每个元素中的各项跟类NetworkConfig的成员变量对应。
这里的处理主要是在声明一个NetworkConfig对象时把每个String元素作为参数,最后把每个NetworkConfig对象加到数组mNetConfigs中。
至此,有关各种网络的配置都保存在数组mNetConfigs里。
接下来,看看mNetConfigs数组是在什么时候派上用场的?
通过阅读源代码,可以知道各种网络在启动的时候,会发出一个message(EVENT_STATE_CHANGED),这个消息会在ConnectivityService的内部类NetworkStateTrackerHandler中被处理。
代码如下:
privateclassNetworkStateTrackerHandlerextendsHandler{
......
@Override
publicvoidhandleMessage(Messagemsg){
NetworkInfoinfo;
switch(msg.what){
caseNetworkStateTracker.EVENT_STATE_CHANGED:
......
if(info.getDetailedState()==
NetworkInfo.DetailedState.FAILED){
handleConnectionFailure(info);
}elseif(info.getDetailedState()==
DetailedState.CAPTIVE_PORTAL_CHECK){
handleCaptivePortalTrackerCheck(info);
}elseif(state==NetworkInfo.State.DISCONNECTED){
handleDisconnect(info);
}elseif(state==NetworkInfo.State.SUSPENDED){
}elseif(state==NetworkInfo.State.CONNECTED){
handleConnect(info);
当网络启动时,最终会调用到函数handleConnect,下面看看handleConnect具体实现:
if(mNetConfigs[newNetType].isDefault()){
if(mActiveDefaultNetwork!
=-1&
mActiveDefaultNetwork!
=newNetType){
if(isNewNetTypePreferredOverCurrentNetType(newNetType)){
//teardowntheother
NetworkStateTrackerotherNet=
mNetTrackers[mActiveDefaultNetwork];
if(DBG){
log("
Policyrequires"
+otherNet.getNetworkInfo().getTypeName()+
teardown"
);
if(!
teardown(otherNet)){
Networkdeclinedteardownrequest"
teardown(thisNet);
return;
}else{
//don'
tacceptthisone
if(VDBG){
NotbroadcastingCONNECT_ACTION"
totorndownnetwork"
+info.getTypeName());
......
mActiveDefaultNetwork=newNetType;
第一个if是判断网络是不是默认路由的,上文提到的config.xml中wifi、Ethernet、mobile都是默认路由的。
第二个if是根据变量mActiveDefaultNetwork来判断是否有其他网络正在运行。
如果有的话,就对两种网络的优先级进行比较。
优先比较是通过函数isNewNetTypePreferredOverCurrentNetType来实现的。
如果返回false则不连接网络并返回。
如果返回true则断开当前网络,并把newNetType赋给mActiveDefaultNetwork,确保之后的网络操作使用的是新的网络连接。
到这里已经完成了网络切换的流程。
下面分析函数isNewNetTypePreferredOverCurrentNetType,代码如下:
privatebooleanisNewNetTypePreferredOverCurrentNetType(inttype){
if((type!
=mNetworkPreference&
mNetConfigs[mActiveDefaultNetwork].priority>
mNetConfigs[type].priority)||
mNetworkPreference==mActiveDefaultNetwork)returnfalse;
returntrue;
函数isNewNetTypePreferredOverCurrentNetType是判断是否切换为新启动的网络。
从函数代码可以发现,变量mNetworkPreference起到了很关键的作用,因为当mActiveDefaultNetwork等于mNetworkPreference时,不管优先级怎样,函数直接返回false。
所以必须搞清楚mNetworkPreference的值到底是什么?
通过查找,知道mNetworkPreference是在ConnectivityService的构造函数中初始化的。
mNetworkPreference=getPersistedNetworkPreference();
下面看一下函数getPersistedNetworkPreference返回的是什么值?
privateintgetPersistedNetworkPreference(){
finalContentResolvercr=mContext.getContentResolver();
finalintnetworkPrefSetting=Settings.Global
.getInt(cr,Settings.Global.NETWORK_PREFERENCE,-1);
if(networkPrefSetting!
=-1){
returnnetworkPrefSetting;
returnConnectivityManager.DEFAULT_NETWORK_PREFERENCE;
第1、2句是获取ContentProvider与Settings.Global.NETWORK_PREFERENCE对应的值。
该ContentProvider是在类DataBaseHelper中初始化,其中有一句关键的代码
db.execSQL("
INSERTINTOsystem('
name'
'
value'
)values('
network_preference'
ConnectivityManager.DEFAULT_NETWORK_PREFERENCE+"
'
)"
可见其实保存的也是ConnectivityManager.DEFAULT_NETWORK_PREFERENCE的值。
至此,可以明确一点,那就是
mNetworkPreference=ConnectivityManager.DEFAULT_NETWORK_PREFERENCE
注意1.将frameworks/base/core/res/res/values/config.xml中的networkAttributes重写被./device/seuic/seuic_6dq/overlay/frameworks/base/core/res/res/values/config.xml中的networkAttributes替代
注意2.默认网络是WIFI
2、AndroidInternet流程
关键类:
.EthernetDataTracker.java
com.android.server.NetworkManagementService.java
com.android.server.NativeDaemonConnector.java
.LocalSocket.java
.LocalSocketImpl.java
frameworks\base\core\jni\android_net_LocalSocketImpl.cpp
./system/core/libcutils/socket_local_client.c
.NetworkUtils.java
\frameworks\base\core\jni\android_net_NetUtils.cpp
/system/core/libnetutils/dhcp_utils.c
以太网启动入口:
/**
*Beginmonitoringconnectivity
*/
publicvoidstartMonitoring(Contextcontext,Handlertarget){
mContext=context;
mCsHandler=target;
finalPowerManagerpowerManager=(PowerManager)context.getSystemService(
Context.POWER_SERVICE);
mEthernetWakeLock=powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,TAG);
//registerfornotificationsfromNetworkManagementService
IBinderb=ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
mNMService=INetworkManagementService.Stub.asInterface(b);
mInterfaceObserver=newInterfaceObserver(this);
//enableandtrytoconnecttoanethernetinterfacethat
//alreadyexists
sIfaceMatch=context.getResources().getString(
com.android.internal.R.string.config_ethernet_iface_regex);
finalString[]ifaces=mNMService.listInterfaces();
for(Stringiface:
ifaces){
if(iface.matches(sIfaceMatch)){
mIface=iface;
mNMService.setInterfaceUp(iface);
InterfaceConfigurationconfig=mNMService.getInterfaceConfig(iface);
if(config!
=null&
mHwAddr==null){
mHwAddr=config.getHardwareAddress();
if(mHwAddr!
mNetworkInfo.setExtraInfo(mHwAddr);
//ifaDHCPclienthadpreviouslybeenstartedforthisinterface,thenstopit
NetworkUtils.stopDhcp(mIface);
reconnect();
break;
}catch(RemoteExceptione){
Log.e(TAG,"
Couldnotgetlistofinterfaces"
+e);
mNMService.registerObserver(mInterfaceObserver);
CouldnotregisterInterfaceObserver"
}
这里先取出一个xml属性
com.android.internal.R.string.config_ethernet_iface_regex
放到sIfaceMatch中,这个一看就是个匹配字符串
这里匹配的是所有eth\\d,查了下JAVA的正则表达式,就是eth0,eth1什么的
mNMService.listInterfaces()
这个什么NMService是NetworkManagerService
显然有call到一个管网络连接的Service去了
跟踪到NetworkManagerService.java
publicString[]listInterfaces(){
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL,TAG);
returnNativeDaemonEvent.filterMessageList(
mConnector.executeForList("
interface"
"
list"
),InterfaceListResult);
}catch(NativeDaemonConnectorExceptione){
throwe.rethrowAsParcelableException();
mConnector:
NativeDaemonConnector
继续跟踪:
publicNativeDaemonEvent[]execute(inttimeout,Stringcmd,Object...args)
throwsNativeDaemonConnectorException{
finallongstartTime=SystemClock.elapsedRealtime();
finalArrayList<
NativeDaemonEvent>
events=Lists.newArrayList();
finalStringBuilderrawBuilder=newStringBuilder();
finalStringBuilderlogBuilder=newStringBuilder();
finalintsequenceNumber=mSequenceNumber.incrementAndGet();
makeCommand(rawBuilder,logBuilder,sequenceNumber,cmd,args);
finalStringrawCmd=rawBuilder.toString();
finalStringlogCmd=logBuilder.toString();
SND->
{"
+logCmd+"
}"
synchronized(mDaemonLock){
if(mOutputStream==null){
thrownewNativeDaemonConnectorException("
missingoutputstream"
mOutputStream.write(rawCmd.getBytes(Charsets.UTF_8));
}catch(IOExceptione){
problemsendingcommand"
e);
NativeDaemonEventevent=null;
do{
event=mResponseQueue.remove(sequenceNumber,timeout,logCmd);
if(event==null){
timed-outwaitingforresponseto"
+logCmd);
thrownewNativeDaemonFailureException(logCmd,event);
RMV<
-{"
+event+"
events.add(event);
}while(event.isClassContinue());
finallongendTime=SystemClock.elapsedRealtime();
if(endTime-startTime>
WARN_EXECUTE_DELAY_MS){
NDCCommand{"
}tooktoolong("
+(endTim