rk3399 android7.1上调试了ap6256芯片(该芯片支持5G wifi) ap

最近在rk3288 android5.1/7.1和rk3399 android7.1上调试了ap6256芯片(该芯片支持5G wifi),但是我打开AP热点时候只能生成2.4G频段的AP。在“设置WLAN热点”里面有一个“选择AP频段”的选项(android5.1没有该开关,这个也是后来我调试5.1的时候才发现的,之后我已经解决了),但是该选项里面只有一个2.4GHz频段的选项,并没有5G频段的选项。之前我在https://blog.youkuaiyun.com/Mrdeath/article/details/103030362里有写怎么打开5G AP,但是该文章的方法是写死的,也就是说只能打开5G热点,没办法2.4G和5G之间切换。不过在设置里面既然有“2.4G频段”的选项,那一定也有5G的选项,其中5G选项应该是被系统隐藏了,因此展开调查,来打开5G选项开关,并能成功设置5G热点。

1.在packages/apps/Settings/目录下搜关键字"2.4 GHz 频段",结果:

packages/apps/Settings/res/values-zh-rCN/strings.xml:    <string name="wifi_ap_choose_2G" msgid="8724267386885036210">"2.4 GHz 频段"</string>
 
 

2.提取到string name :wifi_ap_choose_2G,继续在packages/apps/Settings/目录下搜:

packages/apps/Settings/res/values/arrays.xml:        <item>@string/wifi_ap_choose_2G</item>
 
 

3.进入array.xml查看该xml


 
 
  1. <!-- Wi-Fi AP band settings. Either 2.4GHz or 5GHz. -->
  2. <!-- Note that adding/removing/moving the items will need wifi settings code change. -->
  3. <string-array name="wifi_ap_band_config_full">
  4. <item>@string/wifi_ap_choose_2G </item>
  5. <item>@string/wifi_ap_choose_5G </item>
  6. </string-array>
  7. <string-array name="wifi_ap_band_config_2G_only">
  8. <item>@string/wifi_ap_choose_2G </item>
  9. </string-array>

看到果然是有5G选项对应的字符串:wifi_ap_choose_5G

4.提取wifi_ap_band_config_full字符,在packages/apps/Settings目录下继续搜索:

packages/apps/Settings/src/com/android/settings/wifi/WifiApDialog.java:                    R.array.wifi_ap_band_config_full, android.R.layout.simple_spinner_item);
 
 

5.进到WifiApDialog.java下,查看:


 
 
  1. if (!mWifiManager.isDualBandSupported() || countryCode == null) {
  2. //If no country code, 5GHz AP is forbidden
  3. Log.i(TAG,(!mWifiManager.isDualBandSupported() ? "Device do not support 5GHz " : "")
  4. + (countryCode == null ? " NO country code" : "") + " forbid 5GHz");
  5. channelAdapter = ArrayAdapter.createFromResource(mContext,
  6. R.array.wifi_ap_band_config_2G_only, android.R.layout.simple_spinner_item);
  7. mWifiConfig.apBand = 0;
  8. } else {
  9. channelAdapter = ArrayAdapter.createFromResource(mContext,
  10. R.array.wifi_ap_band_config_full, android.R.layout.simple_spinner_item);
  11. }

这里很明显了,有一个if判断:if (!mWifiManager.isDualBandSupported() || countryCode == null)

也就是mWifiManager.isDualBandSupported() !=null 并且countryCode != null,才能进入wifi_ap_band_config_full模式,

countryCode字面意思就是要有国家代码,在我们中国国内5G信道只允许使用149以上的信道,因此没设置国家是无法使用5G热点的。

国家代码先放一边,先来调查isDualBandSupported的作用:

6.在frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiServiceImpl.java目录下有对isDualBandSupported方法的定义:


 
 
  1. public boolean isDualBandSupported () {
  2. //TODO: Should move towards adding a driver API that checks at runtime
  3. return mContext.getResources().getBoolean(
  4. com.android.internal.R.bool.config_wifi_dual_band_support);
  5. }

从代码中可以理解到,isDualBandSupported方法返回值是个bool类型值,它返回的是config_wifi_dual_band_support所对应的值,因此我们只要去确认config_wifi_dual_band_support是true还是false就可以了,不过现在看来该值应该是被设置成了false,下面我们继续去查找该值真正被设置成了什么:

7.在frameworks/base/core/res/res/values/config.xml目录下,有对config_wifi_dual_band_support值的设置,该值果然是被设置成了false,现在把它改为true。


 
 
  1. <!-- Boolean indicating whether the wifi chipset has dual frequency band support -->
  2. <bool translatable="false" name="config_wifi_dual_band_support">true </bool>

这里设置成true后,isDualBandSupported应该已经是为true了,要想打开5G开关,还需要设置国家代码,继续调查国家代码是如何设置的:

8.我们回到packages/apps/Settings/src/com/android/settings/wifi/WifiApDialog.java目录,查看countryCode是怎么设置的

String countryCode = mWifiManager.getCountryCode();
 
 

在WifiApDialog.java文件里面有对countryCode 的提取:String countryCode = mWifiManager.getCountryCode(),既然有get,那一定有地方set,我们就去找set地方,然而set国家代码是根据phoneNumber去设置的,而我的板子压根就没插SIM卡,我的AP是以太网转AP,因此也不用sim卡,因此,我们只能写死一个中国的countryCode ,在packages/apps/Settings/src/com/android/settings/wifi/WifiApDialog.java里把String countryCode = "CN"; 写死


 
 
  1. ArrayAdapter <CharSequence> channelAdapter;
  2. //String countryCode = mWifiManager.getCountryCode();
  3. String countryCode = "CN"; // 写死为中国国家代码

最终编译烧写完成,打开WLAN热点开关发现,isDualBandSupported返回值还是为false,失败!

于是我尝试把WifiApDialog.java文件里的if判断改掉,改成 只判断国家代码:


 
 
  1. if (countryCode == null){
  2. //if (!mWifiManager.isDualBandSupported() || countryCode == null) {
  3. //If no country code, 5GHz AP is forbidden
  4. Log.i(TAG,(!mWifiManager.isDualBandSupported() ? "Device do not support 5GHz " : "")
  5. + (countryCode == null ? " NO country code" : "") + " forbid 5GHz");
  6. channelAdapter = ArrayAdapter.createFromResource(mContext,
  7. R.array.wifi_ap_band_config_2G_only, android.R.layout.simple_spinner_item);
  8. mWifiConfig.apBand = 0;
  9. } else {
  10. channelAdapter = ArrayAdapter.createFromResource(mContext,
  11. R.array.wifi_ap_band_config_full, android.R.layout.simple_spinner_item);
  12. }

再次编译,烧写测试。在设置栏里面出现了“5G 频段”的选项,但是5Gwifi没法放热点,一设置5G热点就会报错,估计是因为是没有设置5G信道导致的。那就继续往下调查

9.在网络上搜索rk3288 5G AP相关资料后,无意中发现一份《使能5G AP分析》的文档,看了这份文档后发现,它就是去添加5G的信道,刚好符合我的需求,上面所设置的内容加上这篇文章中所写的内容,两者结合应该是可以实现2.4G和5G 热点的切换。

添加5G的补丁:frameworks/opt/net/wifi/service/java/com/android/server/wifi/util/ApConfigUtil.java


 
 
  1. diff --git a/service/java/com/android/server/wifi/util/ApConfigUtil.java b/service/java/com/android/server/wifi/util/ApConfigUtil.java
  2. index 0e12f06..bbf4a11 100644
  3. --- a/service/java/com/android/server/wifi/util/ApConfigUtil.java
  4. +++ b/service/java/com/android/server/wifi/util/ApConfigUtil.java
  5. @@ -33,6 +33,7 @@ public class ApConfigUtil {
  6. public static final int DEFAULT_AP_BAND = WifiConfiguration.AP_BAND_2GHZ;
  7. public static final int DEFAULT_AP_CHANNEL = 6;
  8. + public static final int DEFAULT_AP_CHANNEL_5GHz = 153;
  9. /* Return code for updateConfiguration. */
  10. public static final int SUCCESS = 0;
  11. @@ -115,16 +116,25 @@ public class ApConfigUtil {
  12. WifiConfiguration config) {
  13. /* Use default band and channel for device without HAL. */
  14. if (!wifiNative.isHalStarted()) {
  15. - config.apBand = DEFAULT_AP_BAND;
  16. - config.apChannel = DEFAULT_AP_CHANNEL;
  17. - return SUCCESS;
  18. + //add by louhn
  19. + if (WifiConfiguration.AP_BAND_2GHZ == config.apBand)
  20. + config.apChannel = DEFAULT_AP_CHANNEL;
  21. + else if (WifiConfiguration.AP_BAND_5GHZ == config.apBand)
  22. + config.apChannel = DEFAULT_AP_CHANNEL_5GHz;
  23. + else {
  24. + config.apBand = DEFAULT_AP_BAND;
  25. + config.apChannel = DEFAULT_AP_CHANNEL;
  26. + }
  27. + //add end
  28. + return SUCCESS;
  29. }
  30. /* Country code is mandatory for 5GHz band. */
  31. if (config.apBand == WifiConfiguration.AP_BAND_5GHZ
  32. && countryCode == null) {
  33. - Log.e(TAG, "5GHz band is not allowed without country code");
  34. - return ERROR_GENERIC;
  35. + //Log.e(TAG, "5GHz band is not allowed without country code");
  36. + Log.e(TAG, "5GHz band is not allowed without country code, use channel:153 for 5GHz AP");
  37. + //return ERROR_GENERIC;
  38. }
  39. /* Select a channel if it is not specified. */

打完以上补丁后,5G AP终于能够成功生成,并且2.4G跟5G能够双切换了。

 

最终附上我这次修改的所有补丁,补丁是在rk3399_android7.1上生成的,rk3288也一样参考修改


 
 
  1. diff --git a/src/com/android/settings/wifi/WifiApDialog.java b/src/com/android/settings/wifi/WifiApDialog.java
  2. index 1316a49..41c8f45 100644
  3. --- a/src/com/android/settings/wifi/WifiApDialog.java
  4. +++ b/src/com/android/settings/wifi/WifiApDialog.java
  5. @@ -134,8 +134,18 @@ public class WifiApDialog extends AlertDialog implements View.OnClickListener,
  6. mPassword = (EditText) mView.findViewById(R.id.password);
  7. ArrayAdapter <CharSequence> channelAdapter;
  8. - String countryCode = mWifiManager.getCountryCode();
  9. - if (!mWifiManager.isDualBandSupported() || countryCode == null) {
  10. + //String countryCode = mWifiManager.getCountryCode();
  11. + String countryCode = "CN";
  12. + if( countryCode == null)
  13. + {
  14. + Log.i("LOUHN","countryCode == null");
  15. + }
  16. + if(!mWifiManager.isDualBandSupported())
  17. + {
  18. + Log.i("LOUHN","mWifiManager.isDualBandSupported()=null");
  19. + }
  20. + if (countryCode == null){
  21. + //if (!mWifiManager.isDualBandSupported() || countryCode == null) {
  22. //If no country code, 5GHz AP is forbidden
  23. Log.i(TAG,(!mWifiManager.isDualBandSupported() ? "Device do not support 5GHz " :"")
  24. + (countryCode == null ? " NO country code" :"") + " forbid 5GHz");
  25. diff --git a/service/java/com/android/server/wifi/util/ApConfigUtil.java b/service/java/com/android/server/wifi/util/ApConfigUtil.java
  26. index 0e12f06..bbf4a11 100644
  27. --- a/service/java/com/android/server/wifi/util/ApConfigUtil.java
  28. +++ b/service/java/com/android/server/wifi/util/ApConfigUtil.java
  29. @@ -33,6 +33,7 @@ public class ApConfigUtil {
  30. public static final int DEFAULT_AP_BAND = WifiConfiguration.AP_BAND_2GHZ;
  31. public static final int DEFAULT_AP_CHANNEL = 6;
  32. + public static final int DEFAULT_AP_CHANNEL_5GHz = 153;
  33. /* Return code for updateConfiguration. */
  34. public static final int SUCCESS = 0;
  35. @@ -115,16 +116,25 @@ public class ApConfigUtil {
  36. WifiConfiguration config) {
  37. /* Use default band and channel for device without HAL. */
  38. if (!wifiNative.isHalStarted()) {
  39. - config.apBand = DEFAULT_AP_BAND;
  40. - config.apChannel = DEFAULT_AP_CHANNEL;
  41. - return SUCCESS;
  42. + //add by louhn
  43. + if (WifiConfiguration.AP_BAND_2GHZ == config.apBand)
  44. + config.apChannel = DEFAULT_AP_CHANNEL;
  45. + else if (WifiConfiguration.AP_BAND_5GHZ == config.apBand)
  46. + config.apChannel = DEFAULT_AP_CHANNEL_5GHz;
  47. + else {
  48. + config.apBand = DEFAULT_AP_BAND;
  49. + config.apChannel = DEFAULT_AP_CHANNEL;
  50. + }
  51. + //add end
  52. + return SUCCESS;
  53. }
  54. /* Country code is mandatory for 5GHz band. */
  55. if (config.apBand == WifiConfiguration.AP_BAND_5GHZ
  56. && countryCode == null) {
  57. - Log.e(TAG, "5GHz band is not allowed without country code");
  58. - return ERROR_GENERIC;
  59. + //Log.e(TAG, "5GHz band is not allowed without country code");
  60. + Log.e(TAG, "5GHz band is not allowed without country code, use channel:153 for 5GHz AP");
  61. + //return ERROR_GENERIC;
  62. }
  63. /* Select a channel if it is not specified. */

以上内容是我昨天做rk3288 android7.1和rk3399 android的内容,今天我准备以同样方式在rk3288 android5.1上添加5G AP选择开关的时候发现,rk3288根本就没有预留2.4G和5G AP的选择开关,也就是说,我必须自己写一个开关!好吧,前面那一句“补丁是在rk3399_android7.1上生成的,rk3288也一样参考修改”的话我收回,我们现在就去解决,如何在rk3288android5.1上添加ap频段选择开关。

1.废话不多说,我们先把ap选择开关的界面先做好,参考android7.1的内容我们很快就可以做好5.1的界面,具体过程因为比较简单,我就不啰嗦了,直接放上界面补丁,之后的framework处,我再详细分析说明:


 
 
  1. cd packages/apps/Settings
  2. diff --git a/res/layout/wifi_ap_dialog.xml b/res/layout/wifi_ap_dialog.xml
  3. index 30043c4..f01ec7b 100644
  4. --- a/res/layout/wifi_ap_dialog.xml
  5. +++ b/res/layout/wifi_ap_dialog.xml
  6. @@ -105,5 +105,30 @@
  7. style="@style/wifi_item_content"
  8. android:text="@string/wifi_show_password" />
  9. </LinearLayout>
  10. - </LinearLayout>
  11. +
  12. + <LinearLayout android:id="@+id/fields"
  13. + android:layout_width="match_parent"
  14. + android:layout_height="wrap_content"
  15. + style="@style/wifi_section" >
  16. +
  17. + <LinearLayout
  18. + android:layout_width="match_parent"
  19. + android:layout_height="wrap_content"
  20. + style="@style/wifi_item">
  21. + <TextView
  22. + android:layout_width="match_parent"
  23. + android:layout_height="wrap_content"
  24. + style="@style/wifi_item_label"
  25. + android:layout_marginTop="8dip"
  26. + android:text="@string/wifi_ap_band_config" />
  27. +
  28. + <Spinner android:id="@+id/choose_channel"
  29. + android:layout_width="match_parent"
  30. + android:layout_height="wrap_content"
  31. + style="@style/wifi_item_content"
  32. + android:prompt="@string/wifi_ap_band_config" />
  33. + </LinearLayout>
  34. + </LinearLayout>
  35. +
  36. + </LinearLayout>
  37. </ScrollView>
  38. diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
  39. index 826701e..07a937f 100755
  40. --- a/res/values-zh-rCN/strings.xml
  41. +++ b/res/values-zh-rCN/strings.xml
  42. @@ -669,7 +669,11 @@
  43. <string name="wifi_eap_anonymous" msgid="2989469344116577955">"匿名身份"</string>
  44. <string name="wifi_password" msgid="5948219759936151048">"密码"</string>
  45. <string name="wifi_show_password" msgid="6461249871236968884">"显示密码"</string>
  46. - <string name="wifi_ip_settings" msgid="3359331401377059481">"IP 设置"</string>
  47. + <!--add by louhn-->
  48. + <string name="wifi_ap_band_config" msgid="1611826705989117930">"选择 AP 频段"</string>
  49. + <string name="wifi_ap_choose_2G" msgid="8724267386885036210">"2.4 GHz 频段"</string>
  50. + <string name="wifi_ap_choose_5G" msgid="8137061170937978040">"5 GHz 频段"</string>
  51. + <string name="wifi_ip_settings" msgid="3359331401377059481">"IP 设置"</string>
  52. <string name="wifi_unchanged" msgid="3410422020930397102">"(未更改)"</string>
  53. <string name="wifi_unspecified" msgid="5431501214192991253">"(未指定)"</string>
  54. <string name="wifi_remembered" msgid="4955746899347821096">"已保存"</string>
  55. diff --git a/res/values/arrays.xml b/res/values/arrays.xml
  56. index 3f8602c..b424068 100644
  57. --- a/res/values/arrays.xml
  58. +++ b/res/values/arrays.xml
  59. @@ -420,6 +420,15 @@
  60. <!-- Do not translate. -->
  61. <item>3</item>
  62. </string-array>
  63. +
  64. + <!--add by louhn-->
  65. + <string-array name="wifi_ap_band_config_full">
  66. + <item>@string/wifi_ap_choose_2G</item>
  67. + <item>@string/wifi_ap_choose_5G</item>
  68. + </string-array>
  69. + <string-array name="wifi_ap_band_config_2G_only">
  70. + <item>@string/wifi_ap_choose_2G</item>
  71. + </string-array>
  72. <!-- Data Usage settings. Range of data usage. -->
  73. <string-array name="data_usage_data_range">
  74. diff --git a/res/values/strings.xml b/res/values/strings.xml
  75. index 068df77..9cbbf33 100755
  76. --- a/res/values/strings.xml
  77. +++ b/res/values/strings.xml
  78. @@ -1590,8 +1590,12 @@
  79. <string name="wifi_password">Password</string>
  80. <!-- Label for the check box to show password -->
  81. <string name="wifi_show_password">Show password</string>
  82. - <!-- Label for the spinner to show ip settings [CHAR LIMIT=25] -->
  83. - <string name="wifi_ip_settings">IP settings</string>
  84. + <!-- Label for the spinner to show ip settings [CHAR LIMIT=25] -->
  85. + <!--add by louhn-->
  86. + <string name="wifi_ap_band_config" msgid="1611826705989117930">"Seleccionar banda de AP"</string>
  87. + <string name="wifi_ap_choose_2G" msgid="8724267386885036210">"2.4 GHz Band"</string>
  88. + <string name="wifi_ap_choose_5G" msgid="8137061170937978040">"5 GHz Band"</string>
  89. + <string name="wifi_ip_settings">IP settings</string>
  90. <!-- Hint for unchanged fields -->
  91. <string name="wifi_unchanged">(unchanged)</string>
  92. <!-- Hint for unspecified fields -->
  93. diff --git a/src/com/android/settings/wifi/WifiApDialog.java b/src/com/android/settings/wifi/WifiApDialog.java
  94. index fb8026a..6ec1f6c 100644
  95. --- a/src/com/android/settings/wifi/WifiApDialog.java
  96. +++ b/src/com/android/settings/wifi/WifiApDialog.java
  97. @@ -22,12 +22,15 @@ import android.content.DialogInterface;
  98. import android.net.wifi.WifiConfiguration;
  99. import android.net.wifi.WifiConfiguration.AuthAlgorithm;
  100. import android.net.wifi.WifiConfiguration.KeyMgmt;
  101. +import android.net.wifi.WifiManager;
  102. import android.os.Bundle;
  103. import android.text.Editable;
  104. import android.text.InputType;
  105. import android.text.TextWatcher;
  106. +import android.util.Log;
  107. import android.view.View;
  108. import android.widget.AdapterView;
  109. +import android.widget.ArrayAdapter;
  110. import android.widget.CheckBox;
  111. import android.widget.EditText;
  112. import android.widget.Spinner;
  113. @@ -35,6 +38,8 @@ import android.widget.TextView;
  114. import com.android.settings.R;
  115. +import java.nio.charset.Charset;
  116. +
  117. /**
  118. * Dialog to configure the SSID and security settings
  119. * for Access Point operation
  120. @@ -53,8 +58,13 @@ public class WifiApDialog extends AlertDialog implements View.OnClickListener,
  121. private TextView mSsid;
  122. private int mSecurityTypeIndex = OPEN_INDEX;
  123. private EditText mPassword;
  124. + private int mBandIndex = OPEN_INDEX;
  125. WifiConfiguration mWifiConfig;
  126. + WifiManager mWifiManager;
  127. + private Context mContext;
  128. +
  129. + private static final String TAG = "WifiApDialog";
  130. public WifiApDialog(Context context, DialogInterface.OnClickListener listener,
  131. WifiConfiguration wifiConfig) {
  132. @@ -64,6 +74,8 @@ public class WifiApDialog extends AlertDialog implements View.OnClickListener,
  133. if (wifiConfig != null) {
  134. mSecurityTypeIndex = getSecurityTypeIndex(wifiConfig);
  135. }
  136. + mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
  137. + mContext = context;
  138. }
  139. public static int getSecurityTypeIndex(WifiConfiguration wifiConfig) {
  140. @@ -85,6 +97,8 @@ public class WifiApDialog extends AlertDialog implements View.OnClickListener,
  141. */
  142. config.SSID = mSsid.getText().toString();
  143. + config.apBand = mBandIndex;
  144. +
  145. switch (mSecurityTypeIndex) {
  146. case OPEN_INDEX:
  147. config.allowedKeyManagement.set(KeyMgmt.NONE);
  148. @@ -104,9 +118,10 @@ public class WifiApDialog extends AlertDialog implements View.OnClickListener,
  149. @Override
  150. protected void onCreate(Bundle savedInstanceState) {
  151. -
  152. + boolean mInit = true;
  153. mView = getLayoutInflater().inflate(R.layout.wifi_ap_dialog, null);
  154. Spinner mSecurity = ((Spinner) mView.findViewById(R.id.security));
  155. + final Spinner mChannel = (Spinner) mView.findViewById(R.id.choose_channel);
  156. setView(mView);
  157. setInverseBackgroundForced(true);
  158. @@ -118,18 +133,68 @@ public class WifiApDialog extends AlertDialog implements View.OnClickListener,
  159. mSsid = (TextView) mView.findViewById(R.id.ssid);
  160. mPassword = (EditText) mView.findViewById(R.id.password);
  161. + ArrayAdapter <CharSequence> channelAdapter;
  162. + //String countryCode = mWifiManager.getCountryCode();
  163. + String countryCode = "CN"; //louhn:这里写死为CN
  164. +
  165. + if (countryCode == null) {
  166. + //If no country code, 5GHz AP is forbidden
  167. + Log.i(TAG,(!mWifiManager.isDualBandSupported() ? "Device do not support 5GHz " :"")
  168. + + (countryCode == null ? " NO country code" :"") + " forbid 5GHz");
  169. + channelAdapter = ArrayAdapter.createFromResource(mContext,
  170. + R.array.wifi_ap_band_config_2G_only, android.R.layout.simple_spinner_item);
  171. + mWifiConfig.apBand = 0;
  172. + } else {
  173. + channelAdapter = ArrayAdapter.createFromResource(mContext,
  174. + R.array.wifi_ap_band_config_full, android.R.layout.simple_spinner_item);
  175. + }
  176. +
  177. + channelAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
  178. +
  179. setButton(BUTTON_SUBMIT, context.getString(R.string.wifi_save), mListener);
  180. setButton(DialogInterface.BUTTON_NEGATIVE,
  181. context.getString(R.string.wifi_cancel), mListener);
  182. if (mWifiConfig != null) {
  183. mSsid.setText(mWifiConfig.SSID);
  184. + if (mWifiConfig.apBand == 0) {
  185. + mBandIndex = 0;
  186. + } else {
  187. + mBandIndex = 1;
  188. + }
  189. +
  190. mSecurity.setSelection(mSecurityTypeIndex);
  191. if (mSecurityTypeIndex == WPA2_INDEX) {
  192. - mPassword.setText(mWifiConfig.preSharedKey);
  193. + mPassword.setText(mWifiConfig.preSharedKey);
  194. }
  195. }
  196. + mChannel.setAdapter(channelAdapter);
  197. + mChannel.setOnItemSelectedListener(
  198. + new AdapterView.OnItemSelectedListener() {
  199. + boolean mInit = true;
  200. + @Override
  201. + public void onItemSelected(AdapterView<?> adapterView, View view, int position,
  202. + long id) {
  203. + if (!mInit) {
  204. + mBandIndex = position;
  205. + mWifiConfig.apBand = mBandIndex;
  206. + Log.i(TAG, "config on channelIndex : " + mBandIndex + " Band: " +
  207. + mWifiConfig.apBand);
  208. + } else {
  209. + mInit = false;
  210. + mChannel.setSelection(mBandIndex);
  211. + }
  212. +
  213. + }
  214. +
  215. + @Override
  216. + public void onNothingSelected(AdapterView<?> adapterView) {
  217. +
  218. + }
  219. + }
  220. + );
  221. +
  222. mSsid.addTextChangedListener(this);
  223. mPassword.addTextChangedListener(this);
  224. ((CheckBox) mView.findViewById(R.id.show_password)).setOnClickListener(this);
  225. @@ -141,10 +206,21 @@ public class WifiApDialog extends AlertDialog implements View.OnClickListener,
  226. validate();
  227. }
  228. + public void onRestoreInstanceState(Bundle savedInstanceState) {
  229. + super.onRestoreInstanceState(savedInstanceState);
  230. + mPassword.setInputType(
  231. + InputType.TYPE_CLASS_TEXT |
  232. + (((CheckBox) mView.findViewById(R.id.show_password)).isChecked() ?
  233. + InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD :
  234. + InputType.TYPE_TEXT_VARIATION_PASSWORD));
  235. + }
  236. +
  237. private void validate() {
  238. - if ((mSsid != null && mSsid.length() == 0) ||
  239. - ((mSecurityTypeIndex == WPA2_INDEX)&&
  240. - mPassword.length() < 8)) {
  241. + String mSsidString = mSsid.getText().toString();
  242. + if ((mSsid != null && mSsid.length() == 0)
  243. + || ((mSecurityTypeIndex == WPA2_INDEX) && mPassword.length() < 8)
  244. + || (mSsid != null &&
  245. + Charset.forName("UTF-8").encode(mSsidString).limit() > 32)) {
  246. getButton(BUTTON_SUBMIT).setEnabled(false);
  247. } else {
  248. getButton(BUTTON_SUBMIT).setEnabled(true);

2.打上上面那个补丁后,你在界面上设置里面的“设置WLAN热点”的list里面应该就能看到2.4G和5G频段的热点选择开关,但是该开关没有作用,无论是选择2.4G还是5G,放出来的热点都是只有2.4G的。之后我们就来解决如何把5G AP的功能加入到5G的选择按钮上:

2.1、一开始我没有头绪,我们就从7.1的源码开始找思路,先把7.1的源码理顺了,再去修改5.1的代码。

我们从7.1的frameworks/opt/net/wifi/service/java/com/android/server/wifi/util/ApConfigUtil.java文件出发,看它是如何设置2.4G和5G的选择的:


 
 
  1. public static int updateApChannelConfig (WifiNative wifiNative,
  2. String countryCode,
  3. ArrayList<Integer> allowed2GChannels,
  4. WifiConfiguration config) {
  5. /* Use default band and channel for device without HAL. */
  6. if (!wifiNative.isHalStarted()) {
  7. //add by louhn
  8. if (WifiConfiguration.AP_BAND_2GHZ == config.apBand)
  9. config.apChannel = DEFAULT_AP_CHANNEL;
  10. else if (WifiConfiguration.AP_BAND_5GHZ == config.apBand)
  11. config.apChannel = DEFAULT_AP_CHANNEL_5GHz;
  12. else {
  13. config.apBand = DEFAULT_AP_BAND;
  14. config.apChannel = DEFAULT_AP_CHANNEL;
  15. }
  16. //add end
  17. return SUCCESS;
  18. }

在updateApChannelConfig方法里面是根据config.apBand这个值来设置判断现在选择的是2.4G还是5G,而这个config又是从哪里传来的呢?继续调查updateApChannelConfig是从哪里调用的。

2.2、搜索发现,frameworks/opt/net/wifi/service/java/com/android/server/wifi/SoftApManager.java目录下有调用updateApChannelConfig方法,直接进去看具体的情况:


 
 
  1. private int startSoftAp (WifiConfiguration config) {
  2. if (config == null) {
  3. Log.e(TAG, "Unable to start soft AP without configuration");
  4. return ERROR_GENERIC;
  5. }
  6. /* Make a copy of configuration for updating AP band and channel. */
  7. WifiConfiguration localConfig = new WifiConfiguration(config);
  8. int result = ApConfigUtil.updateApChannelConfig(
  9. mWifiNative, mCountryCode, mAllowed2GChannels, localConfig);
  10. if (result != SUCCESS) {
  11. Log.e(TAG, "Failed to update AP band and channel");
  12. return result;
  13. }
  14. /* Setup country code if it is provide. */
  15. if (mCountryCode != null) {
  16. /**
  17. * Country code is mandatory for 5GHz band, return an error if failed to set
  18. * country code when AP is configured for 5GHz band.
  19. */

一个叫startSoftAp(WifiConfiguration config)方法里面,调用了updateApChannelConfig方法,而传入的localConfig就是我们要找的config,这个localConfig是WifiConfiguration localConfig =  WifiConfiguration(config);赋值的,我们再去查找startSoftAp是在哪里被调用的:

2.3、还是在frameworks/opt/net/wifi/service/java/com/android/server/wifi/SoftApManager.java目录下就有startSoftAp被调用的方法:


 
 
  1. private class IdleState extends State {
  2. @Override
  3. public boolean processMessage (Message message) {
  4. switch (message.what) {
  5. case CMD_START:
  6. updateApState(WifiManager.WIFI_AP_STATE_ENABLING, 0);
  7. int result = startSoftAp((WifiConfiguration) message.obj);
  8. if (result == SUCCESS) {
  9. updateApState(WifiManager.WIFI_AP_STATE_ENABLED, 0);
  10. transitionTo(mStartedState);
  11. } else {
  12. int reason = WifiManager.SAP_START_FAILURE_GENERAL;
  13. if (result == ERROR_NO_CHANNEL) {
  14. reason = WifiManager.SAP_START_FAILURE_NO_CHANNEL;
  15. }
  16. updateApState(WifiManager.WIFI_AP_STATE_FAILED, reason);
  17. }
  18. break;
  19. default:
  20. /* Ignore all other commands. */
  21. break;
  22. }
  23. return HANDLED;

而传入的值是message.obj,这里先把这个值放一边,先调查startSoftAp是如何被调用的,这里是switch进到case CMD_START后startSoftAp才被调用的,CMD_START字面意思我们试着去猜测一下:应该是处于开始打开AP的阶段,我们再在目录下搜索CMD_START是哪里被定义的:


 
 
  1. private class SoftApStateMachine extends StateMachine {
  2. /* Commands for the state machine. */
  3. public static final int CMD_START = 0;
  4. public static final int CMD_STOP = 1;
  5. private final State mIdleState = new IdleState();
  6. private final State mStartedState = new StartedState();
  7. SoftApStateMachine(Looper looper) {
  8. super(TAG, looper);
  9. addState(mIdleState);
  10. addState(mStartedState, mIdleState);
  11. setInitialState(mIdleState);
  12. start();
  13. }

SoftApStateMachine类里面有对CMD_START的定义,那顺理成章的我们再搜索SoftApStateMachine.CMD_START是在哪里被使用到的:


 
 
  1. /**
  2. * Start soft AP with given configuration.
  3. * @param config AP configuration
  4. */
  5. public void start (WifiConfiguration config) {
  6. mStateMachine.sendMessage(SoftApStateMachine.CMD_START, config);
  7. }

还是在当前目录,有个start方法,有发送SoftApStateMachine.CMD_START,继续搜索SoftApManager.start

2.4、在frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java目录下,有调用mSoftApManager.start,我们进入源码查看:


 
 
  1. @Override
  2. public void enter () {
  3. final Message message = getCurrentMessage();
  4. if (message.what == CMD_START_AP) {
  5. WifiConfiguration config = (WifiConfiguration) message.obj;
  6. if (config == null) {
  7. /**
  8. * Configuration not provided in the command, fallback to use the current
  9. * configuration.
  10. */
  11. config = mWifiApConfigStore.getApConfiguration();
  12. } else {
  13. /* Update AP configuration. */
  14. mWifiApConfigStore.setApConfiguration(config);
  15. }
  16. checkAndSetConnectivityInstance();
  17. mSoftApManager = mFacade.makeSoftApManager(
  18. mContext, getHandler().getLooper(), mWifiNative, mNwService,
  19. mCm, mCountryCode.getCountryCode(),
  20. mWifiApConfigStore.getAllowed2GChannel(),
  21. new SoftApListener());
  22. mSoftApManager.start(config);
  23. } else {
  24. throw new RuntimeException( "Illegal transition to SoftApState: " + message);
  25. }
  26. }

mSoftApManager.start(config)是在Message接收到CMD_START_AP后执行的,而config值是WifiConfiguration config = (WifiConfiguration) message.obj赋值的,待会儿我们查看5.1代码时候,也进到这个目录下查看5.1在这个地方具体做了什么,我们再来看下config是怎么定义的,config的类是WifiConfiguration,我们直接搜索WifiConfiguration.java:

2.5:frameworks/base/wifi/java/android/net/wifi/WifiConfiguration.java:WifiConfiguration这个类里面定义了ssid,bssid,psk,scan_ssid等等等等,而之前我们的5G选择按钮AP_BAND_5GHZ也是在这里添加的,因为5.1压根就没有2.4G与5G的选择按钮,所以在5.1的WifiConfiguration.java目录下,也一定要添加对应的2.4G和5G的选择

因此我们回到5.1,在5.1上把WifiConfiguration.java文件里添加2.4G和5G的选择开关:


 
 
  1. diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
  2. index 87db951..c9963b9 100644
  3. --- a/wifi/java/android/net/wifi/WifiConfiguration.java
  4. +++ b/wifi/java/android/net/wifi/WifiConfiguration.java
  5. @@ -237,6 +237,36 @@ public class WifiConfiguration implements Parcelable {
  6. * Fully qualified domain name (FQDN) of AAA server or RADIUS server
  7. * e.g. {@code "mail.example.com"}.
  8. */
  9. +
  10. + /**
  11. + * 2GHz band.
  12. + * @hide
  13. + */
  14. + public static final int AP_BAND_2GHZ = 0;
  15. +
  16. + /**
  17. + * 5GHz band.
  18. + * @hide
  19. + */
  20. + public static final int AP_BAND_5GHZ = 1;
  21. +
  22. + /**
  23. + * The band which AP resides on
  24. + * 0-2G 1-5G
  25. + * By default, 2G is chosen
  26. + * @hide
  27. + */
  28. + public int apBand = AP_BAND_2GHZ;
  29. +
  30. + /**
  31. + * The channel which AP resides on,currently, US only
  32. + * 2G 1-11
  33. + * 5G 36,40,44,48,149,153,157,161,165
  34. + * 0 - find a random available channel according to the apBand
  35. + * @hide
  36. + */
  37. + public int apChannel = 0;
  38. +
  39. public String FQDN;
  40. /**
  41. * Network access identifier (NAI) realm, for Passpoint credential.
  42. @@ -1500,7 +1530,10 @@ public class WifiConfiguration implements Parcelable {
  43. FQDN = source.FQDN;
  44. naiRealm = source.naiRealm;
  45. preSharedKey = source.preSharedKey;
  46. -
  47. + //add by louhn
  48. + apBand = source.apBand;
  49. + apChannel = source.apChannel;
  50. + //add end
  51. wepKeys = new String[4];
  52. for (int i = 0; i < wepKeys.length; i++) {
  53. wepKeys[i] = source.wepKeys[i];
  54. @@ -1593,7 +1626,11 @@ public class WifiConfiguration implements Parcelable {
  55. dest.writeInt(disableReason);
  56. dest.writeString(SSID);
  57. dest.writeString(BSSID);
  58. - dest.writeString(autoJoinBSSID);
  59. + //add by louhn
  60. + dest.writeInt(apBand);
  61. + dest.writeInt(apChannel);
  62. + //end
  63. + dest.writeString(autoJoinBSSID);
  64. dest.writeString(FQDN);
  65. dest.writeString(naiRealm);
  66. dest.writeString(preSharedKey);
  67. @@ -1658,7 +1695,11 @@ public class WifiConfiguration implements Parcelable {
  68. config.disableReason = in.readInt();
  69. config.SSID = in.readString();
  70. config.BSSID = in.readString();
  71. - config.autoJoinBSSID = in.readString();
  72. + //add by louhn
  73. + config.apBand = in.readInt();
  74. + config.apChannel = in.readInt();
  75. + //add end
  76. + config.autoJoinBSSID = in.readString();
  77. config.FQDN = in.readString();
  78. config.naiRealm = in.readString();
  79. config.preSharedKey = in.readString();

再回到5.1的frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java,查看5.1在SoftApState处具体做了什么:


 
 
  1. class SoftApStartingState extends State {
  2. @Override
  3. public void enter () {
  4. final Message message = getCurrentMessage();
  5. if (message.what == CMD_START_AP) {
  6. final WifiConfiguration config = (WifiConfiguration) message.obj;
  7. if (config == null) {
  8. mWifiApConfigChannel.sendMessage(CMD_REQUEST_AP_CONFIG);
  9. } else {
  10. mWifiApConfigChannel.sendMessage(CMD_SET_AP_CONFIG, config);
  11. startSoftApWithConfig(config);
  12. }
  13. } else {
  14. throw new RuntimeException( "Illegal transition to SoftApStartingState: " + message);
  15. }
  16. }
  17. @Override
  18. public boolean processMessage (Message message) {
  19. logStateAndMessage(message, getClass().getSimpleName());
  20. switch(message.what) {
  21. case CMD_START_SUPPLICANT:
  22. case CMD_STOP_SUPPLICANT:
  23. case CMD_START_AP:
  24. case CMD_STOP_AP:
  25. case CMD_START_DRIVER:
  26. case CMD_STOP_DRIVER:
  27. case CMD_SET_OPERATIONAL_MODE:
  28. case CMD_SET_COUNTRY_CODE:
  29. case CMD_SET_FREQUENCY_BAND:
  30. case CMD_START_PACKET_FILTERING:
  31. case CMD_STOP_PACKET_FILTERING:
  32. case CMD_TETHER_STATE_CHANGE:
  33. deferMessage(message);
  34. break;
  35. case WifiStateMachine.CMD_RESPONSE_AP_CONFIG:
  36. WifiConfiguration config = (WifiConfiguration) message.obj;
  37. if (config != null) {
  38. startSoftApWithConfig(config);
  39. } else {
  40. loge( "Softap config is null!");
  41. sendMessage(CMD_START_AP_FAILURE);
  42. }
  43. break;
  44. case CMD_START_AP_SUCCESS:
  45. setWifiApState(WIFI_AP_STATE_ENABLED);
  46. transitionTo(mSoftApStartedState);
  47. break;
  48. case CMD_START_AP_FAILURE:
  49. setWifiApState(WIFI_AP_STATE_FAILED);
  50. transitionTo(mInitialState);
  51. break;
  52. default:
  53. return NOT_HANDLED;
  54. }
  55. return HANDLED;
  56. }
  57. }

android5.1源码里面不叫SoftApState而是叫SoftApStartingState,这里有个判断if (config == null),则else执行startSoftApWithConfig(config),进入到startSoftApWithConfig方法,查看该方法具体做了什么:

还是在本目录下:


 
 
  1. private void startSoftApWithConfig (final WifiConfiguration config) {
  2. // Start hostapd on a separate thread
  3. new Thread( new Runnable() {
  4. public void run () {
  5. try {
  6. mNwService.startAccessPoint(config, mInterfaceName);
  7. } catch (Exception e) {
  8. loge( "Exception in softap start " + e);
  9. try {
  10. mNwService.stopAccessPoint(mInterfaceName);
  11. mNwService.startAccessPoint(config, mInterfaceName);
  12. } catch (Exception e1) {
  13. loge( "Exception in softap re-start " + e1);
  14. sendMessage(CMD_START_AP_FAILURE);
  15. return;
  16. }
  17. }
  18. if (DBG) log( "Soft AP start successful");
  19. sendMessage(CMD_START_AP_SUCCESS);
  20. if(!mSoftApWakeLock.isHeld()) {
  21. loge( "---- mSoftApWakeLock.acquire ----");
  22. mSoftApWakeLock.acquire();
  23. }
  24. }
  25. }).start();
  26. }

该方法回去执行mNwService.startAccessPoint(config, mInterfaceName);我们再继续搜索mNwService.startAccessPoint做了什么

在frameworks/base/services/core/java/com/android/server/NetworkManagementService.java里,有对startAccessPoint的定义,进入目录,继续查看。终于,我们在startAccessPoint里找到了我们想看到的内容:


 
 
  1. mConnector.execute( "softap", "set", wlanIface, wifiConfig.SSID,
  2. "broadcast", "6", getSecurityType(wifiConfig),
  3. new SensitiveArg(wifiConfig.preSharedKey));

设置wifi的SSID,信道等等,这里我们可以看到只传入了一个“6”,也就是说,只设置了2.4G的热点,那么我们可以在这里做一个选择,根据2.4G和5G的选择开关,去选择到底是打开2.4G还是5G:


 
 
  1. diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
  2. index 18bf838..857fff4 100644
  3. --- a/services/core/java/com/android/server/NetworkManagementService.java
  4. +++ b/services/core/java/com/android/server/NetworkManagementService.java
  5. @@ -1365,10 +1365,29 @@ public class NetworkManagementService extends INetworkManagementService.Stub
  6. if (wifiConfig == null) {
  7. mConnector.execute("softap", "set", wlanIface);
  8. } else {
  9. - mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID,
  10. + //add by louhn
  11. + if(wifiConfig.apBand == 0)//AP_BAND_2GHZ
  12. + {
  13. + mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID,
  14. + "broadcast", "6", getSecurityType(wifiConfig),
  15. + new SensitiveArg(wifiConfig.preSharedKey));
  16. + Log.e("LOUHN", "wifiConfig.apBand: AP_BAND_2GHZ");
  17. + }
  18. + else if(wifiConfig.apBand == 1)//AP_BAND_5GHZ
  19. + {
  20. + mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID,
  21. + "broadcast", "153", getSecurityType(wifiConfig),
  22. + new SensitiveArg(wifiConfig.preSharedKey));
  23. + Log.e("LOUHN", "wifiConfig.apBand: AP_BAND_5GHZ");
  24. + }
  25. + else
  26. + {
  27. + mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID,
  28. "broadcast", "6", getSecurityType(wifiConfig),
  29. new SensitiveArg(wifiConfig.preSharedKey));
  30. - }
  31. + Log.e("LOUHN", "Don't know wifiConfig.apBand");
  32. + }
  33. + }
  34. mConnector.execute("softap", "startap");
  35. } catch (NativeDaemonConnectorException e) {
  36. throw e.rethrowAsParcelableException();

最终编译烧写验证,该2.4G/5G开关生效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

攻城狮2015

你得打赏,是我的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值