Bootstrap

android 4.1 "Mobile networks" 选项 不存在

1、“Mobile networks”字符串定义

我们想要的数据没有显示,从不显示的字符找起。“Mobile networks”不显示,那我们就从最开始跟下代码吧。

  1. 4.1/packages/apps/Settings/res/values/String.xml  
  2.   <!-- Wireless controls, item title to go into the network settings -->   
  3.   <string name="network_settings_title">Mobile networks</string>  

2、network_settings_title引用

  1. 4.1/packages/apps/Settings/src/com/android/settings/WirelessSettings.java中找到:"mobile_network_settings"  
  2.   private static final String KEY_MOBILE_NETWORK_SETTINGS = "mobile_network_settings";   

network_settings_title赋值给 KEY_MOBILE_NETWORK_SETTINGS,再跟进一下 KEY_MOBILE_NETWORK_SETTINGS这个变量吧。

在相同的文件中我们找到:

  1. // Remove Mobile Network Settings if it's a wifi-only device.   
  2.  if (Utils.isWifiOnly(getActivity())) {   
  3.  getPreferenceScreen().removePreference(findPreference(KEY_MOBILE_NETWORK_SETTINGS));   
  4.  }   

3、我们去看下ifWifiOnly()是何方神圣?

packages/apps/Settings/src/com/android/settings/Utils.java中找到

  1. import android.net.ConnectivityManager;  
  2.    
  3. public static boolean isWifiOnly(Context context) {  
  4. ConnectivityManager cm = (ConnectivityManager)context.getSystemService(  
  5. Context.CONNECTIVITY_SERVICE);  
  6. return (cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false);  


getSystemService(Context.CONNECTIVITY_SERVICE);获得网络连接服务,然后判断是否支持TYPE_MOBILE,现在判断应该是不支持,也就是if判断中:Utils.isWifiOnly(getActivity())=1,所以把移动网络的选项移除,现在我们就重点去分析Utils.isWifiOnly(getActivity()),找到不显示的原因,也就是if()中的判断条件,跟进这段代码。我们继续往下看cm.isNetworkSupported

4、 再分析isNetworkSupported

android.net.ConnectivityManager;找到

4.1/frameworks/base/core/java/android/net/ ConnectivityManager.java

isNetworkSupported的实现如下:

  1. public boolean isNetworkSupported(int networkType) {  
  2. try {  
  3. return mService.isNetworkSupported(networkType);  
  4. catch (RemoteException e) {}  
  5. return false;  
  6. }  
  7. }  


继续跟进 mService.isNetworkSupported这个函数的实现

5、 mService.isNetworkSupported的实现

/frameworks/base/services/java/com/android/server/ ConnectivityService.java

  1. @Override   
  2. public boolean isNetworkSupported(int networkType) {   
  3. enforceAccessPermission();   
  4. loge("xu_bin"+"test typevalid = " + isNetworkTypeValid(networkType) + " trackers = " + (mNetTrackers[networkType] != null));   
  5. return (isNetworkTypeValid(networkType) && (mNetTrackers[networkType] != null));   
  6. }  

有两个参数: isNetworkTypeValid(networkType) (mNetTrackers[networkType] != null))

我们要的值是ture,可返回是false,看下这两个值是什么,把这连个值打印出来:

loge("xu_bin"+"test typevalid = " + isNetworkTypeValid(networkType) + " trackers = " + (mNetTrackers[networkType] != null));

打印结果为:

打印结果为:

i/ConnectivityService( 1426): xu_bin test typevalid = true trackers = false

 

也就是说:(mNetTrackers[networkType] != null)这个地方出问题;

即mNetTrackers[networkType] ==null

6、我们在看下:mNetTrackers[networkType]的由来吧

其实下面这段代码我有点蒙,连猜带蒙的,

4.0.3_r1/frameworks/base/services/java/com/android/server/ ConnectivityManager.java

  1. public ConnectivityService(Context context, INetworkManagementService netd,  
  2.   INetworkStatsService statsService, INetworkPolicyManager policyManager)  
  3. {  
  4.   if (DBG) log("ConnectivityService starting up");  
  5.            …………  
  6.   // Load device network attributes from resources  
  7.   String[] raStrings = context.getResources().getStringArray(  
  8.   com.android.internal.R.array.radioAttributes);  
  9.   for (String raString : raStrings) {  
  10.           loge("xu_bin test raStrings" + raStrings); // 1  
  11.           loge("xu_bin test raString" + raString);  
  12.   RadioAttributes r = new RadioAttributes(raString);  
  13.   if (r.mType > ConnectivityManager.MAX_RADIO_TYPE) {  
  14.   loge("Error in radioAttributes - ignoring attempt to define type " + r.mType);  
  15.   continue;  
  16.   }  
  17.   if (mRadioAttributes[r.mType] != null) {  
  18.   loge("Error in radioAttributes - ignoring attempt to redefine type " +  
  19.   r.mType);  
  20.   continue;  
  21.   }  
  22.   mRadioAttributes[r.mType] = r;  
  23.   }  
  24.    
  25.   String[] naStrings = context.getResources().getStringArray(  
  26.   com.android.internal.R.array.networkAttributes);  
  27.    
  28.   for (String naString : naStrings) {  
  29.           loge("xu_bin test naStrings" + naStrings);//2  
  30.           loge("xu_bin test naString" + naString);  
  31.   try {  
  32.   NetworkConfig n = new NetworkConfig(naString);  
  33.   if (n.type > ConnectivityManager.MAX_NETWORK_TYPE) {  
  34.   loge("Error in networkAttributes - ignoring attempt to define type " +  
  35.   n.type);  
  36.   continue;  
  37.   }  
  38.   if (mNetConfigs[n.type] != null) {  
  39.   loge("Error in networkAttributes - ignoring attempt to redefine type " +  
  40.   n.type);  
  41.   continue;  
  42.   }  
  43.   …………  
  44.   /* 
  45.   * Create the network state trackers for Wi-Fi and mobile 
  46.   * data. Maybe this could be done with a factory class, 
  47.   * but it's not clear that it's worth it, given that 
  48.   * the number of different network types is not going 
  49.   * to change very often. 
  50.   */  
  51.   for (int netType : mPriorityList) {  
  52. loge("xu_bin:" + netType + " " + mNetConfigs[netType].radio + " " + ConnectivityManager.TYPE_MOBILE);  
  53. loge("xu_bin test mNetConfigs[netType].radio =" + (mNetConfigs[netType].radio));//3  
  54.   switch (mNetConfigs[netType].radio) {   
  55.    
  56.                       …………  
  57.   case ConnectivityManager.TYPE_MOBILE:  
  58.   mNetTrackers[netType] = new MobileDataStateTracker(netType,  
  59.   mNetConfigs[netType].name);  
  60.   mNetTrackers[netType].startMonitoring(context, mHandler);  
  61.   break;  
  62.   case ConnectivityManager.TYPE_DUMMY:  
  63.   mNetTrackers[netType] = new DummyDataStateTracker(netType,  
  64.   mNetConfigs[netType].name);  
  65.   mNetTrackers[netType].startMonitoring(context, mHandler);  
  66.   break;  
  67.                       …………  
  68.   case ConnectivityManager.TYPE_ETHERNET:  
  69.   mNetTrackers[netType] = EthernetDataTracker.getInstance();  
  70.   mNetTrackers[netType].startMonitoring(context, mHandler);  
  71.   break;  
  72.   default:  
  73.   loge("Trying to create a DataStateTracker for an unknown radio type " +  
  74.   mNetConfigs[netType].radio);  
  75.   continue;  
  76.   }  
  77.   mCurrentLinkProperties[netType] = null;  
  78.   if (mNetTrackers[netType] != null && mNetConfigs[netType].isDefault()) {  
  79.   mNetTrackers[netType].reconnect();  
  80.   }  
  81.   }  
  82.    
  83.   …………  
  84.   }  

加入打印信息:

1)、

loge("xu_bin test raStrings" + raStrings);

loge("xu_bin test raString" + raString);

2)、

loge("xu_bin test naStrings" + naStrings);

loge("xu_bin test naString" + naString);

3)、

loge("xu_bin:" + netType + " " + mNetConfigs[netType].radio + " " + ConnectivityManager.TYPE_MOBILE);

loge("xu_bin test mNetConfigs[netType].radio =" + (mNetConfigs[netType].radio));

  1. 打印出来的值如下:  
  2. E/ConnectivityService( 1426): xu_bin test raString s[Ljava.lang.String;@411cf008   
  3. E/ConnectivityService( 1426): xu_bin test raString 9,1   
  4. E/ConnectivityService( 1426): xu_bin test naString s[Ljava.lang.String;@410e30c8   
  5. E/ConnectivityService( 1426): xu_bin test naString ethernet,9,9,1,-1,true   
  6. E/ConnectivityService( 1426): xu_bin:9 9 0   
  7. E/ConnectivityService( 1426): xu_bin test mNetConfigs[netType].radio =9   
  8. D/NetworkManagementService( 1426): Registering observer   
  9. D/NetworkManagementService( 1426): Registering observer   
  10. D/NetworkManagementService( 1426): Registering observer   
  11. I/WifiService( 1426): WifiService starting up with Wi-Fi disabled   
  12. E/ConnectivityService( 1426): xu_bintest typevalid = true trackers = false  
  13. <span style="font-family:宋体;FONT-SIZE: 10.5pt" lang="EN-US">com.android.internal.R.array.networkAttributes</span><span style="font-family:宋体;FONT-SIZE: 10.5pt">的值在:<span lang="EN-US"><o:p></o:p></span></span>  

我们在:4.0.3_r1/frameworks/base/core/res/res/values/config.xml

  1. <string-array translatable="false" name="networkAttributes">   
  2.   <item>"wifi,1,1,1,-1,true"</item>   
  3.   <item>"mobile,0,0,0,-1,true"</item>   
  4.   <item>"mobile_mms,2,0,2,60000,true"</item>   
  5.   <item>"mobile_supl,3,0,2,60000,true"</item>   
  6.   <item>"mobile_hipri,5,0,3,60000,true"</item>   
  7.   <item>"mobile_fota,10,0,2,60000,true"</item>   
  8.   <item>"mobile_ims,11,0,2,60000,true"</item>   
  9.   <item>"mobile_cbs,12,0,2,60000,true"</item>   
  10.   <item>"wifi_p2p,13,1,0,-1,true"</item>   
  11.   </string-array>  

这里面并没有:ethernet,9,9,1,-1,true ,所以我们全局搜索一下:

grep -r -w ethernet ./*得到下面有用信息:

  1. ./android-samsung-dev.patch:- <item>"ethernet,9,9,2,-1,true"</item>   
  2. ./android-samsung-dev.patch:+           // Following code will forcefully allow ethernet network as usable required for v310/c210.   
  3. ./packages/providers/DownloadProvider/src/com/android/providers/downloads/DownloadThread.java:          // Following code will forcefully allow ethernet network as usable required for v310/c210.   
  4. ./device/samsung/smdkv310/overlay/frameworks/base/core/res/res/values/config.xml: <item>"ethernet,9,9,1,-1,true"</item>  
  5.    

对比代码发现:

./packages/providers/DownloadProvider/src/com/android/providers/downloads/DownloadThread.java中删除

  1.  Following code will forcefully allow ethernet network as usable required for v310/c210.   
  2. if (networkUsable != DownloadInfo.NETWORK_OK) {   
  3. Log.i(Constants.TAG, " Forcing ethernet connection usable for download to work!!!");   
  4.           networkUsable = DownloadInfo.NETWORK_OK;   
  5.         }  

4.0.3_r1/device/samsung/smdkv310/overlay/frameworks/base/core/res/res/values/config.xml中删除:

  1. <!-- This string array should be overridden by the device to present a list of network   
  2. attributes. This is used by the connectivity manager to decide which networks can coexist   
  3. based on the hardware -->   
  4. <!-- An Array of "[Connection name],[ConnectivityManager connection type],   
  5. [associated radio-type],[priority],[restoral-timer(ms)],[dependencyMet] -->   
  6. <!-- the 5th element "resore-time" indicates the number of milliseconds to delay   
  7. before automatically restore the default connection. Set -1 if the connection   
  8. does not require auto-restore. -->   
  9. <!-- the 6th element indicates boot-time dependency-met value. -->   
  10. <string-array translatable="false" name="networkAttributes">   
  11. <item>"ethernet,9,9,1,-1,true"</item>   
  12. </string-array>   
  13.   
  14. <!-- This string array should be overridden by the device to present a list of radio   
  15. attributes. This is used by the connectivity manager to decide which networks can coexist   
  16. based on the hardware -->   
  17. <!-- An Array of "[ConnectivityManager connectionType],   
  18. [# simultaneous connection types]" -->   
  19. <string-array translatable="false" name="radioAttributes">   
  20. <item>"9,1"</item>   
  21. </string-array>  


把上面两部分删除就可以了。其实真正的值是在4.0.3_r1/frameworks/base/core/res/res/values/config.xml中,通过上面函数解析。

正常情况下打印值为:如:wifi mobile mobile_mms mobile_supl等都是在config.xml中配置的

  1. D/ConnectivityService( 1397): ConnectivityService starting up  
  2. E/ConnectivityService( 1397): xu_bin test restring s[Ljava.lang.String;@41240e38  
  3. E/ConnectivityService( 1397): xu_bin test restring 1,1  
  4. E/ConnectivityService( 1397): xu_bin test restring s[Ljava.lang.String;@41240e38  
  5. E/ConnectivityService( 1397): xu_bin test restring 0,1  
  6. E/ConnectivityService( 1397): xu_bin test naString s[Ljava.lang.String;@41241880  
  7. E/ConnectivityService( 1397): xu_bin test naString wifi,1,1,1,-1,true  
  8. E/ConnectivityService( 1397): xu_bin test naString s[Ljava.lang.String;@41241880  
  9. E/ConnectivityService( 1397): xu_bin test naString mobile,0,0,0,-1,true  
  10. E/ConnectivityService( 1397): xu_bin test naString s[Ljava.lang.String;@41241880  
  11. E/ConnectivityService( 1397): xu_bin test naString mobile_mms,2,0,2,60000,true  
  12. E/ConnectivityService( 1397): xu_bin test naString s[Ljava.lang.String;@41241880  
  13. E/ConnectivityService( 1397): xu_bin test naString mobile_supl,3,0,2,60000,true  
  14. E/ConnectivityService( 1397): xu_bin test naString s[Ljava.lang.String;@41241880  
  15. E/ConnectivityService( 1397): xu_bin test naString mobile_hipri,5,0,3,60000,true  
  16. E/ConnectivityService( 1397): xu_bin test naString s[Ljava.lang.String;@41241880  
  17. E/ConnectivityService( 1397): xu_bin test naString mobile_fota,10,0,2,60000,true  
  18. E/ConnectivityService( 1397): xu_bin test naString s[Ljava.lang.String;@41241880  
  19. E/ConnectivityService( 1397): xu_bin test naString mobile_ims,11,0,2,60000,true  
  20. E/ConnectivityService( 1397): xu_bin test naString s[Ljava.lang.String;@41241880  
  21. E/ConnectivityService( 1397): xu_bin test naString mobile_cbs,12,0,2,60000,true  
  22. E/ConnectivityService( 1397): xu_bin test naString s[Ljava.lang.String;@41241880  
  23. E/ConnectivityService( 1397): xu_bin test naString wifi_p2p,13,1,0,-1,true 
;