最近在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
-
<!-- Wi-Fi AP band settings. Either 2.4GHz or 5GHz. -->
-
<!-- Note that adding/removing/moving the items will need wifi settings code change. -->
-
<string-array name="wifi_ap_band_config_full">
-
<item>@string/wifi_ap_choose_2G
</item>
-
<item>@string/wifi_ap_choose_5G
</item>
-
</string-array>
-
-
<string-array name="wifi_ap_band_config_2G_only">
-
<item>@string/wifi_ap_choose_2G
</item>
-
</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下,查看:
-
if (!mWifiManager.isDualBandSupported() || countryCode ==
null) {
-
//If no country code, 5GHz AP is forbidden
-
Log.i(TAG,(!mWifiManager.isDualBandSupported() ?
"Device do not support 5GHz " :
"")
-
+ (countryCode ==
null ?
" NO country code" :
"") +
" forbid 5GHz");
-
channelAdapter = ArrayAdapter.createFromResource(mContext,
-
R.array.wifi_ap_band_config_2G_only, android.R.layout.simple_spinner_item);
-
mWifiConfig.apBand =
0;
-
}
else {
-
channelAdapter = ArrayAdapter.createFromResource(mContext,
-
R.array.wifi_ap_band_config_full, android.R.layout.simple_spinner_item);
-
}
这里很明显了,有一个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方法的定义:
-
public
boolean
isDualBandSupported
() {
-
//TODO: Should move towards adding a driver API that checks at runtime
-
return mContext.getResources().getBoolean(
-
com.android.internal.R.bool.config_wifi_dual_band_support);
-
}
从代码中可以理解到,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。
-
<!-- Boolean indicating whether the wifi chipset has dual frequency band support -->
-
<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"; 写死
-
ArrayAdapter <CharSequence> channelAdapter;
-
//String countryCode = mWifiManager.getCountryCode();
-
String
countryCode
=
"CN";
// 写死为中国国家代码
最终编译烧写完成,打开WLAN热点开关发现,isDualBandSupported返回值还是为false,失败!
于是我尝试把WifiApDialog.java文件里的if判断改掉,改成 只判断国家代码:
-
if (countryCode ==
null){
-
//if (!mWifiManager.isDualBandSupported() || countryCode == null) {
-
//If no country code, 5GHz AP is forbidden
-
Log.i(TAG,(!mWifiManager.isDualBandSupported() ?
"Device do not support 5GHz " :
"")
-
+ (countryCode ==
null ?
" NO country code" :
"") +
" forbid 5GHz");
-
channelAdapter = ArrayAdapter.createFromResource(mContext,
-
R.array.wifi_ap_band_config_2G_only, android.R.layout.simple_spinner_item);
-
mWifiConfig.apBand =
0;
-
}
else {
-
channelAdapter = ArrayAdapter.createFromResource(mContext,
-
R.array.wifi_ap_band_config_full, android.R.layout.simple_spinner_item);
-
}
再次编译,烧写测试。在设置栏里面出现了“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
-
diff --git a/service/java/com/android/server/wifi/util/ApConfigUtil.java b/service/java/com/android/server/wifi/util/ApConfigUtil.java
-
index 0e12f06..bbf4a11 100644
-
--- a/service/java/com/android/server/wifi/util/ApConfigUtil.java
-
+++ b/service/java/com/android/server/wifi/util/ApConfigUtil.java
-
@@ -33,6 +33,7 @@ public class ApConfigUtil {
-
-
public static final int DEFAULT_AP_BAND = WifiConfiguration.AP_BAND_2GHZ;
-
public static final int DEFAULT_AP_CHANNEL = 6;
-
+ public static final int DEFAULT_AP_CHANNEL_5GHz = 153;
-
-
/* Return code for updateConfiguration. */
-
public static final int SUCCESS = 0;
-
@@ -115,16 +116,25 @@ public class ApConfigUtil {
-
WifiConfiguration config) {
-
/* Use default band and channel for device without HAL. */
-
if (!wifiNative.isHalStarted()) {
-
- config.apBand = DEFAULT_AP_BAND;
-
- config.apChannel = DEFAULT_AP_CHANNEL;
-
- return SUCCESS;
-
+ //add by louhn
-
+ if (WifiConfiguration.AP_BAND_2GHZ == config.apBand)
-
+ config.apChannel = DEFAULT_AP_CHANNEL;
-
+ else if (WifiConfiguration.AP_BAND_5GHZ == config.apBand)
-
+ config.apChannel = DEFAULT_AP_CHANNEL_5GHz;
-
+ else {
-
+ config.apBand = DEFAULT_AP_BAND;
-
+ config.apChannel = DEFAULT_AP_CHANNEL;
-
+ }
-
+ //add end
-
+ return SUCCESS;
-
}
-
-
/* Country code is mandatory for 5GHz band. */
-
if (config.apBand == WifiConfiguration.AP_BAND_5GHZ
-
&& countryCode == null) {
-
- Log.e(TAG, "5GHz band is not allowed without country code");
-
- return ERROR_GENERIC;
-
+ //Log.e(TAG, "5GHz band is not allowed without country code");
-
+ Log.e(TAG, "5GHz band is not allowed without country code, use channel:153 for 5GHz AP");
-
+ //return ERROR_GENERIC;
-
}
-
-
/* Select a channel if it is not specified. */
打完以上补丁后,5G AP终于能够成功生成,并且2.4G跟5G能够双切换了。
最终附上我这次修改的所有补丁,补丁是在rk3399_android7.1上生成的,rk3288也一样参考修改
-
diff --git a/src/com/android/settings/wifi/WifiApDialog.java b/src/com/android/settings/wifi/WifiApDialog.java
-
index 1316a49..41c8f45 100644
-
--- a/src/com/android/settings/wifi/WifiApDialog.java
-
+++ b/src/com/android/settings/wifi/WifiApDialog.java
-
@@ -134,8 +134,18 @@ public class WifiApDialog extends AlertDialog implements View.OnClickListener,
-
mPassword = (EditText) mView.findViewById(R.id.password);
-
-
ArrayAdapter <CharSequence> channelAdapter;
-
- String countryCode = mWifiManager.getCountryCode();
-
- if (!mWifiManager.isDualBandSupported() || countryCode == null) {
-
+ //String countryCode = mWifiManager.getCountryCode();
-
+ String countryCode = "CN";
-
+ if( countryCode == null)
-
+ {
-
+ Log.i("LOUHN","countryCode == null");
-
+ }
-
+ if(!mWifiManager.isDualBandSupported())
-
+ {
-
+ Log.i("LOUHN","mWifiManager.isDualBandSupported()=null");
-
+ }
-
+ if (countryCode == null){
-
+ //if (!mWifiManager.isDualBandSupported() || countryCode == null) {
-
//If no country code, 5GHz AP is forbidden
-
Log.i(TAG,(!mWifiManager.isDualBandSupported() ? "Device do not support 5GHz " :"")
-
+ (countryCode == null ? " NO country code" :"") + " forbid 5GHz");
-
-
diff --git a/service/java/com/android/server/wifi/util/ApConfigUtil.java b/service/java/com/android/server/wifi/util/ApConfigUtil.java
-
index 0e12f06..bbf4a11 100644
-
--- a/service/java/com/android/server/wifi/util/ApConfigUtil.java
-
+++ b/service/java/com/android/server/wifi/util/ApConfigUtil.java
-
@@ -33,6 +33,7 @@ public class ApConfigUtil {
-
-
public static final int DEFAULT_AP_BAND = WifiConfiguration.AP_BAND_2GHZ;
-
public static final int DEFAULT_AP_CHANNEL = 6;
-
+ public static final int DEFAULT_AP_CHANNEL_5GHz = 153;
-
-
/* Return code for updateConfiguration. */
-
public static final int SUCCESS = 0;
-
@@ -115,16 +116,25 @@ public class ApConfigUtil {
-
WifiConfiguration config) {
-
/* Use default band and channel for device without HAL. */
-
if (!wifiNative.isHalStarted()) {
-
- config.apBand = DEFAULT_AP_BAND;
-
- config.apChannel = DEFAULT_AP_CHANNEL;
-
- return SUCCESS;
-
+ //add by louhn
-
+ if (WifiConfiguration.AP_BAND_2GHZ == config.apBand)
-
+ config.apChannel = DEFAULT_AP_CHANNEL;
-
+ else if (WifiConfiguration.AP_BAND_5GHZ == config.apBand)
-
+ config.apChannel = DEFAULT_AP_CHANNEL_5GHz;
-
+ else {
-
+ config.apBand = DEFAULT_AP_BAND;
-
+ config.apChannel = DEFAULT_AP_CHANNEL;
-
+ }
-
+ //add end
-
+ return SUCCESS;
-
}
-
-
/* Country code is mandatory for 5GHz band. */
-
if (config.apBand == WifiConfiguration.AP_BAND_5GHZ
-
&& countryCode == null) {
-
- Log.e(TAG, "5GHz band is not allowed without country code");
-
- return ERROR_GENERIC;
-
+ //Log.e(TAG, "5GHz band is not allowed without country code");
-
+ Log.e(TAG, "5GHz band is not allowed without country code, use channel:153 for 5GHz AP");
-
+ //return ERROR_GENERIC;
-
}
-
-
/* 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处,我再详细分析说明:
-
cd packages/apps/Settings
-
diff --git a/res/layout/wifi_ap_dialog.xml b/res/layout/wifi_ap_dialog.xml
-
index 30043c4..f01ec7b 100644
-
--- a/res/layout/wifi_ap_dialog.xml
-
+++ b/res/layout/wifi_ap_dialog.xml
-
@@ -105,5 +105,30 @@
-
style="@style/wifi_item_content"
-
android:text="@string/wifi_show_password" />
-
</LinearLayout>
-
- </LinearLayout>
-
+
-
+ <LinearLayout android:id="@+id/fields"
-
+ android:layout_width="match_parent"
-
+ android:layout_height="wrap_content"
-
+ style="@style/wifi_section" >
-
+
-
+ <LinearLayout
-
+ android:layout_width="match_parent"
-
+ android:layout_height="wrap_content"
-
+ style="@style/wifi_item">
-
+ <TextView
-
+ android:layout_width="match_parent"
-
+ android:layout_height="wrap_content"
-
+ style="@style/wifi_item_label"
-
+ android:layout_marginTop="8dip"
-
+ android:text="@string/wifi_ap_band_config" />
-
+
-
+ <Spinner android:id="@+id/choose_channel"
-
+ android:layout_width="match_parent"
-
+ android:layout_height="wrap_content"
-
+ style="@style/wifi_item_content"
-
+ android:prompt="@string/wifi_ap_band_config" />
-
+ </LinearLayout>
-
+ </LinearLayout>
-
+
-
+ </LinearLayout>
-
</ScrollView>
-
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
-
index 826701e..07a937f 100755
-
--- a/res/values-zh-rCN/strings.xml
-
+++ b/res/values-zh-rCN/strings.xml
-
@@ -669,7 +669,11 @@
-
<string name="wifi_eap_anonymous" msgid="2989469344116577955">"匿名身份"</string>
-
<string name="wifi_password" msgid="5948219759936151048">"密码"</string>
-
<string name="wifi_show_password" msgid="6461249871236968884">"显示密码"</string>
-
- <string name="wifi_ip_settings" msgid="3359331401377059481">"IP 设置"</string>
-
+ <!--add by louhn-->
-
+ <string name="wifi_ap_band_config" msgid="1611826705989117930">"选择 AP 频段"</string>
-
+ <string name="wifi_ap_choose_2G" msgid="8724267386885036210">"2.4 GHz 频段"</string>
-
+ <string name="wifi_ap_choose_5G" msgid="8137061170937978040">"5 GHz 频段"</string>
-
+ <string name="wifi_ip_settings" msgid="3359331401377059481">"IP 设置"</string>
-
<string name="wifi_unchanged" msgid="3410422020930397102">"(未更改)"</string>
-
<string name="wifi_unspecified" msgid="5431501214192991253">"(未指定)"</string>
-
<string name="wifi_remembered" msgid="4955746899347821096">"已保存"</string>
-
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
-
index 3f8602c..b424068 100644
-
--- a/res/values/arrays.xml
-
+++ b/res/values/arrays.xml
-
@@ -420,6 +420,15 @@
-
<!-- Do not translate. -->
-
<item>3</item>
-
</string-array>
-
+
-
+ <!--add by louhn-->
-
+ <string-array name="wifi_ap_band_config_full">
-
+ <item>@string/wifi_ap_choose_2G</item>
-
+ <item>@string/wifi_ap_choose_5G</item>
-
+ </string-array>
-
+ <string-array name="wifi_ap_band_config_2G_only">
-
+ <item>@string/wifi_ap_choose_2G</item>
-
+ </string-array>
-
-
<!-- Data Usage settings. Range of data usage. -->
-
<string-array name="data_usage_data_range">
-
diff --git a/res/values/strings.xml b/res/values/strings.xml
-
index 068df77..9cbbf33 100755
-
--- a/res/values/strings.xml
-
+++ b/res/values/strings.xml
-
@@ -1590,8 +1590,12 @@
-
<string name="wifi_password">Password</string>
-
<!-- Label for the check box to show password -->
-
<string name="wifi_show_password">Show password</string>
-
- <!-- Label for the spinner to show ip settings [CHAR LIMIT=25] -->
-
- <string name="wifi_ip_settings">IP settings</string>
-
+ <!-- Label for the spinner to show ip settings [CHAR LIMIT=25] -->
-
+ <!--add by louhn-->
-
+ <string name="wifi_ap_band_config" msgid="1611826705989117930">"Seleccionar banda de AP"</string>
-
+ <string name="wifi_ap_choose_2G" msgid="8724267386885036210">"2.4 GHz Band"</string>
-
+ <string name="wifi_ap_choose_5G" msgid="8137061170937978040">"5 GHz Band"</string>
-
+ <string name="wifi_ip_settings">IP settings</string>
-
<!-- Hint for unchanged fields -->
-
<string name="wifi_unchanged">(unchanged)</string>
-
<!-- Hint for unspecified fields -->
-
diff --git a/src/com/android/settings/wifi/WifiApDialog.java b/src/com/android/settings/wifi/WifiApDialog.java
-
index fb8026a..6ec1f6c 100644
-
--- a/src/com/android/settings/wifi/WifiApDialog.java
-
+++ b/src/com/android/settings/wifi/WifiApDialog.java
-
@@ -22,12 +22,15 @@ import android.content.DialogInterface;
-
import android.net.wifi.WifiConfiguration;
-
import android.net.wifi.WifiConfiguration.AuthAlgorithm;
-
import android.net.wifi.WifiConfiguration.KeyMgmt;
-
+import android.net.wifi.WifiManager;
-
import android.os.Bundle;
-
import android.text.Editable;
-
import android.text.InputType;
-
import android.text.TextWatcher;
-
+import android.util.Log;
-
import android.view.View;
-
import android.widget.AdapterView;
-
+import android.widget.ArrayAdapter;
-
import android.widget.CheckBox;
-
import android.widget.EditText;
-
import android.widget.Spinner;
-
@@ -35,6 +38,8 @@ import android.widget.TextView;
-
-
import com.android.settings.R;
-
-
+import java.nio.charset.Charset;
-
+
-
/**
-
* Dialog to configure the SSID and security settings
-
* for Access Point operation
-
@@ -53,8 +58,13 @@ public class WifiApDialog extends AlertDialog implements View.OnClickListener,
-
private TextView mSsid;
-
private int mSecurityTypeIndex = OPEN_INDEX;
-
private EditText mPassword;
-
+ private int mBandIndex = OPEN_INDEX;
-
-
WifiConfiguration mWifiConfig;
-
+ WifiManager mWifiManager;
-
+ private Context mContext;
-
+
-
+ private static final String TAG = "WifiApDialog";
-
-
public WifiApDialog(Context context, DialogInterface.OnClickListener listener,
-
WifiConfiguration wifiConfig) {
-
@@ -64,6 +74,8 @@ public class WifiApDialog extends AlertDialog implements View.OnClickListener,
-
if (wifiConfig != null) {
-
mSecurityTypeIndex = getSecurityTypeIndex(wifiConfig);
-
}
-
+ mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
-
+ mContext = context;
-
}
-
-
public static int getSecurityTypeIndex(WifiConfiguration wifiConfig) {
-
@@ -85,6 +97,8 @@ public class WifiApDialog extends AlertDialog implements View.OnClickListener,
-
*/
-
config.SSID = mSsid.getText().toString();
-
-
+ config.apBand = mBandIndex;
-
+
-
switch (mSecurityTypeIndex) {
-
case OPEN_INDEX:
-
config.allowedKeyManagement.set(KeyMgmt.NONE);
-
@@ -104,9 +118,10 @@ public class WifiApDialog extends AlertDialog implements View.OnClickListener,
-
-
@Override
-
protected void onCreate(Bundle savedInstanceState) {
-
-
-
+ boolean mInit = true;
-
mView = getLayoutInflater().inflate(R.layout.wifi_ap_dialog, null);
-
Spinner mSecurity = ((Spinner) mView.findViewById(R.id.security));
-
+ final Spinner mChannel = (Spinner) mView.findViewById(R.id.choose_channel);
-
-
setView(mView);
-
setInverseBackgroundForced(true);
-
@@ -118,18 +133,68 @@ public class WifiApDialog extends AlertDialog implements View.OnClickListener,
-
mSsid = (TextView) mView.findViewById(R.id.ssid);
-
mPassword = (EditText) mView.findViewById(R.id.password);
-
-
+ ArrayAdapter <CharSequence> channelAdapter;
-
+ //String countryCode = mWifiManager.getCountryCode();
-
+ String countryCode = "CN"; //louhn:这里写死为CN
-
+
-
+ if (countryCode == null) {
-
+ //If no country code, 5GHz AP is forbidden
-
+ Log.i(TAG,(!mWifiManager.isDualBandSupported() ? "Device do not support 5GHz " :"")
-
+ + (countryCode == null ? " NO country code" :"") + " forbid 5GHz");
-
+ channelAdapter = ArrayAdapter.createFromResource(mContext,
-
+ R.array.wifi_ap_band_config_2G_only, android.R.layout.simple_spinner_item);
-
+ mWifiConfig.apBand = 0;
-
+ } else {
-
+ channelAdapter = ArrayAdapter.createFromResource(mContext,
-
+ R.array.wifi_ap_band_config_full, android.R.layout.simple_spinner_item);
-
+ }
-
+
-
+ channelAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
-
+
-
setButton(BUTTON_SUBMIT, context.getString(R.string.wifi_save), mListener);
-
setButton(DialogInterface.BUTTON_NEGATIVE,
-
context.getString(R.string.wifi_cancel), mListener);
-
-
if (mWifiConfig != null) {
-
mSsid.setText(mWifiConfig.SSID);
-
+ if (mWifiConfig.apBand == 0) {
-
+ mBandIndex = 0;
-
+ } else {
-
+ mBandIndex = 1;
-
+ }
-
+
-
mSecurity.setSelection(mSecurityTypeIndex);
-
if (mSecurityTypeIndex == WPA2_INDEX) {
-
- mPassword.setText(mWifiConfig.preSharedKey);
-
+ mPassword.setText(mWifiConfig.preSharedKey);
-
}
-
}
-
-
+ mChannel.setAdapter(channelAdapter);
-
+ mChannel.setOnItemSelectedListener(
-
+ new AdapterView.OnItemSelectedListener() {
-
+ boolean mInit = true;
-
+ @Override
-
+ public void onItemSelected(AdapterView<?> adapterView, View view, int position,
-
+ long id) {
-
+ if (!mInit) {
-
+ mBandIndex = position;
-
+ mWifiConfig.apBand = mBandIndex;
-
+ Log.i(TAG, "config on channelIndex : " + mBandIndex + " Band: " +
-
+ mWifiConfig.apBand);
-
+ } else {
-
+ mInit = false;
-
+ mChannel.setSelection(mBandIndex);
-
+ }
-
+
-
+ }
-
+
-
+ @Override
-
+ public void onNothingSelected(AdapterView<?> adapterView) {
-
+
-
+ }
-
+ }
-
+ );
-
+
-
mSsid.addTextChangedListener(this);
-
mPassword.addTextChangedListener(this);
-
((CheckBox) mView.findViewById(R.id.show_password)).setOnClickListener(this);
-
@@ -141,10 +206,21 @@ public class WifiApDialog extends AlertDialog implements View.OnClickListener,
-
validate();
-
}
-
-
+ public void onRestoreInstanceState(Bundle savedInstanceState) {
-
+ super.onRestoreInstanceState(savedInstanceState);
-
+ mPassword.setInputType(
-
+ InputType.TYPE_CLASS_TEXT |
-
+ (((CheckBox) mView.findViewById(R.id.show_password)).isChecked() ?
-
+ InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD :
-
+ InputType.TYPE_TEXT_VARIATION_PASSWORD));
-
+ }
-
+
-
private void validate() {
-
- if ((mSsid != null && mSsid.length() == 0) ||
-
- ((mSecurityTypeIndex == WPA2_INDEX)&&
-
- mPassword.length() < 8)) {
-
+ String mSsidString = mSsid.getText().toString();
-
+ if ((mSsid != null && mSsid.length() == 0)
-
+ || ((mSecurityTypeIndex == WPA2_INDEX) && mPassword.length() < 8)
-
+ || (mSsid != null &&
-
+ Charset.forName("UTF-8").encode(mSsidString).limit() > 32)) {
-
getButton(BUTTON_SUBMIT).setEnabled(false);
-
} else {
-
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的选择的:
-
public
static
int
updateApChannelConfig
(WifiNative wifiNative,
-
String countryCode,
-
ArrayList<Integer> allowed2GChannels,
-
WifiConfiguration config) {
-
/* Use default band and channel for device without HAL. */
-
if (!wifiNative.isHalStarted()) {
-
//add by louhn
-
if (WifiConfiguration.AP_BAND_2GHZ == config.apBand)
-
config.apChannel = DEFAULT_AP_CHANNEL;
-
else
if (WifiConfiguration.AP_BAND_5GHZ == config.apBand)
-
config.apChannel = DEFAULT_AP_CHANNEL_5GHz;
-
else {
-
config.apBand = DEFAULT_AP_BAND;
-
config.apChannel = DEFAULT_AP_CHANNEL;
-
}
-
//add end
-
return SUCCESS;
-
}
在updateApChannelConfig方法里面是根据config.apBand这个值来设置判断现在选择的是2.4G还是5G,而这个config又是从哪里传来的呢?继续调查updateApChannelConfig是从哪里调用的。
2.2、搜索发现,frameworks/opt/net/wifi/service/java/com/android/server/wifi/SoftApManager.java目录下有调用updateApChannelConfig方法,直接进去看具体的情况:
-
private
int
startSoftAp
(WifiConfiguration config) {
-
if (config ==
null) {
-
Log.e(TAG,
"Unable to start soft AP without configuration");
-
return ERROR_GENERIC;
-
}
-
-
/* Make a copy of configuration for updating AP band and channel. */
-
WifiConfiguration
localConfig
=
new
WifiConfiguration(config);
-
-
int
result
= ApConfigUtil.updateApChannelConfig(
-
mWifiNative, mCountryCode, mAllowed2GChannels, localConfig);
-
if (result != SUCCESS) {
-
Log.e(TAG,
"Failed to update AP band and channel");
-
return result;
-
}
-
-
/* Setup country code if it is provide. */
-
if (mCountryCode !=
null) {
-
/**
-
* Country code is mandatory for 5GHz band, return an error if failed to set
-
* country code when AP is configured for 5GHz band.
-
*/
一个叫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被调用的方法:
-
private
class
IdleState
extends
State {
-
@Override
-
public
boolean
processMessage
(Message message) {
-
switch (message.what) {
-
case CMD_START:
-
updateApState(WifiManager.WIFI_AP_STATE_ENABLING,
0);
-
int
result
= startSoftAp((WifiConfiguration) message.obj);
-
if (result == SUCCESS) {
-
updateApState(WifiManager.WIFI_AP_STATE_ENABLED,
0);
-
transitionTo(mStartedState);
-
}
else {
-
int
reason
= WifiManager.SAP_START_FAILURE_GENERAL;
-
if (result == ERROR_NO_CHANNEL) {
-
reason = WifiManager.SAP_START_FAILURE_NO_CHANNEL;
-
}
-
updateApState(WifiManager.WIFI_AP_STATE_FAILED, reason);
-
}
-
break;
-
default:
-
/* Ignore all other commands. */
-
break;
-
}
-
return HANDLED;
而传入的值是message.obj,这里先把这个值放一边,先调查startSoftAp是如何被调用的,这里是switch进到case CMD_START后startSoftAp才被调用的,CMD_START字面意思我们试着去猜测一下:应该是处于开始打开AP的阶段,我们再在目录下搜索CMD_START是哪里被定义的:
-
private
class
SoftApStateMachine
extends
StateMachine {
-
/* Commands for the state machine. */
-
public
static
final
int
CMD_START
=
0;
-
public
static
final
int
CMD_STOP
=
1;
-
-
private
final
State
mIdleState
=
new
IdleState();
-
private
final
State
mStartedState
=
new
StartedState();
-
-
SoftApStateMachine(Looper looper) {
-
super(TAG, looper);
-
-
addState(mIdleState);
-
addState(mStartedState, mIdleState);
-
-
setInitialState(mIdleState);
-
start();
-
}
SoftApStateMachine类里面有对CMD_START的定义,那顺理成章的我们再搜索SoftApStateMachine.CMD_START是在哪里被使用到的:
-
/**
-
* Start soft AP with given configuration.
-
* @param config AP configuration
-
*/
-
public
void
start
(WifiConfiguration config) {
-
mStateMachine.sendMessage(SoftApStateMachine.CMD_START, config);
-
}
还是在当前目录,有个start方法,有发送SoftApStateMachine.CMD_START,继续搜索SoftApManager.start
2.4、在frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java目录下,有调用mSoftApManager.start,我们进入源码查看:
-
@Override
-
public
void
enter
() {
-
final
Message
message
= getCurrentMessage();
-
if (message.what == CMD_START_AP) {
-
WifiConfiguration
config
= (WifiConfiguration) message.obj;
-
-
if (config ==
null) {
-
/**
-
* Configuration not provided in the command, fallback to use the current
-
* configuration.
-
*/
-
config = mWifiApConfigStore.getApConfiguration();
-
}
else {
-
/* Update AP configuration. */
-
mWifiApConfigStore.setApConfiguration(config);
-
}
-
-
checkAndSetConnectivityInstance();
-
mSoftApManager = mFacade.makeSoftApManager(
-
mContext, getHandler().getLooper(), mWifiNative, mNwService,
-
mCm, mCountryCode.getCountryCode(),
-
mWifiApConfigStore.getAllowed2GChannel(),
-
new
SoftApListener());
-
mSoftApManager.start(config);
-
}
else {
-
throw
new
RuntimeException(
"Illegal transition to SoftApState: " + message);
-
}
-
}
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的选择开关:
-
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
-
index 87db951..c9963b9 100644
-
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
-
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
-
@@ -237,6 +237,36 @@ public class WifiConfiguration implements Parcelable {
-
* Fully qualified domain name (FQDN) of AAA server or RADIUS server
-
* e.g. {@code "mail.example.com"}.
-
*/
-
+
-
+ /**
-
+ * 2GHz band.
-
+ * @hide
-
+ */
-
+ public static final int AP_BAND_2GHZ = 0;
-
+
-
+ /**
-
+ * 5GHz band.
-
+ * @hide
-
+ */
-
+ public static final int AP_BAND_5GHZ = 1;
-
+
-
+ /**
-
+ * The band which AP resides on
-
+ * 0-2G 1-5G
-
+ * By default, 2G is chosen
-
+ * @hide
-
+ */
-
+ public int apBand = AP_BAND_2GHZ;
-
+
-
+ /**
-
+ * The channel which AP resides on,currently, US only
-
+ * 2G 1-11
-
+ * 5G 36,40,44,48,149,153,157,161,165
-
+ * 0 - find a random available channel according to the apBand
-
+ * @hide
-
+ */
-
+ public int apChannel = 0;
-
+
-
public String FQDN;
-
/**
-
* Network access identifier (NAI) realm, for Passpoint credential.
-
@@ -1500,7 +1530,10 @@ public class WifiConfiguration implements Parcelable {
-
FQDN = source.FQDN;
-
naiRealm = source.naiRealm;
-
preSharedKey = source.preSharedKey;
-
-
-
+ //add by louhn
-
+ apBand = source.apBand;
-
+ apChannel = source.apChannel;
-
+ //add end
-
wepKeys = new String[4];
-
for (int i = 0; i < wepKeys.length; i++) {
-
wepKeys[i] = source.wepKeys[i];
-
@@ -1593,7 +1626,11 @@ public class WifiConfiguration implements Parcelable {
-
dest.writeInt(disableReason);
-
dest.writeString(SSID);
-
dest.writeString(BSSID);
-
- dest.writeString(autoJoinBSSID);
-
+ //add by louhn
-
+ dest.writeInt(apBand);
-
+ dest.writeInt(apChannel);
-
+ //end
-
+ dest.writeString(autoJoinBSSID);
-
dest.writeString(FQDN);
-
dest.writeString(naiRealm);
-
dest.writeString(preSharedKey);
-
@@ -1658,7 +1695,11 @@ public class WifiConfiguration implements Parcelable {
-
config.disableReason = in.readInt();
-
config.SSID = in.readString();
-
config.BSSID = in.readString();
-
- config.autoJoinBSSID = in.readString();
-
+ //add by louhn
-
+ config.apBand = in.readInt();
-
+ config.apChannel = in.readInt();
-
+ //add end
-
+ config.autoJoinBSSID = in.readString();
-
config.FQDN = in.readString();
-
config.naiRealm = in.readString();
-
config.preSharedKey = in.readString();
再回到5.1的frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java,查看5.1在SoftApState处具体做了什么:
-
class
SoftApStartingState
extends
State {
-
@Override
-
public
void
enter
() {
-
final
Message
message
= getCurrentMessage();
-
if (message.what == CMD_START_AP) {
-
final
WifiConfiguration
config
= (WifiConfiguration) message.obj;
-
-
if (config ==
null) {
-
mWifiApConfigChannel.sendMessage(CMD_REQUEST_AP_CONFIG);
-
}
else {
-
mWifiApConfigChannel.sendMessage(CMD_SET_AP_CONFIG, config);
-
startSoftApWithConfig(config);
-
}
-
}
else {
-
throw
new
RuntimeException(
"Illegal transition to SoftApStartingState: " + message);
-
}
-
}
-
@Override
-
public
boolean
processMessage
(Message message) {
-
logStateAndMessage(message, getClass().getSimpleName());
-
-
switch(message.what) {
-
case CMD_START_SUPPLICANT:
-
case CMD_STOP_SUPPLICANT:
-
case CMD_START_AP:
-
case CMD_STOP_AP:
-
case CMD_START_DRIVER:
-
case CMD_STOP_DRIVER:
-
case CMD_SET_OPERATIONAL_MODE:
-
case CMD_SET_COUNTRY_CODE:
-
case CMD_SET_FREQUENCY_BAND:
-
case CMD_START_PACKET_FILTERING:
-
case CMD_STOP_PACKET_FILTERING:
-
case CMD_TETHER_STATE_CHANGE:
-
deferMessage(message);
-
break;
-
case WifiStateMachine.CMD_RESPONSE_AP_CONFIG:
-
WifiConfiguration
config
= (WifiConfiguration) message.obj;
-
if (config !=
null) {
-
startSoftApWithConfig(config);
-
}
else {
-
loge(
"Softap config is null!");
-
sendMessage(CMD_START_AP_FAILURE);
-
}
-
break;
-
case CMD_START_AP_SUCCESS:
-
setWifiApState(WIFI_AP_STATE_ENABLED);
-
transitionTo(mSoftApStartedState);
-
break;
-
case CMD_START_AP_FAILURE:
-
setWifiApState(WIFI_AP_STATE_FAILED);
-
transitionTo(mInitialState);
-
break;
-
default:
-
return NOT_HANDLED;
-
}
-
return HANDLED;
-
}
-
}
android5.1源码里面不叫SoftApState而是叫SoftApStartingState,这里有个判断if (config == null),则else执行startSoftApWithConfig(config),进入到startSoftApWithConfig方法,查看该方法具体做了什么:
还是在本目录下:
-
private
void
startSoftApWithConfig
(final WifiConfiguration config) {
-
// Start hostapd on a separate thread
-
new
Thread(
new
Runnable() {
-
public
void
run
() {
-
try {
-
mNwService.startAccessPoint(config, mInterfaceName);
-
}
catch (Exception e) {
-
loge(
"Exception in softap start " + e);
-
try {
-
mNwService.stopAccessPoint(mInterfaceName);
-
mNwService.startAccessPoint(config, mInterfaceName);
-
}
catch (Exception e1) {
-
loge(
"Exception in softap re-start " + e1);
-
sendMessage(CMD_START_AP_FAILURE);
-
return;
-
}
-
}
-
if (DBG) log(
"Soft AP start successful");
-
sendMessage(CMD_START_AP_SUCCESS);
-
if(!mSoftApWakeLock.isHeld()) {
-
loge(
"---- mSoftApWakeLock.acquire ----");
-
mSoftApWakeLock.acquire();
-
}
-
}
-
}).start();
-
}
该方法回去执行mNwService.startAccessPoint(config, mInterfaceName);我们再继续搜索mNwService.startAccessPoint做了什么
在frameworks/base/services/core/java/com/android/server/NetworkManagementService.java里,有对startAccessPoint的定义,进入目录,继续查看。终于,我们在startAccessPoint里找到了我们想看到的内容:
-
mConnector.execute(
"softap",
"set", wlanIface, wifiConfig.SSID,
-
"broadcast",
"6", getSecurityType(wifiConfig),
-
new
SensitiveArg(wifiConfig.preSharedKey));
设置wifi的SSID,信道等等,这里我们可以看到只传入了一个“6”,也就是说,只设置了2.4G的热点,那么我们可以在这里做一个选择,根据2.4G和5G的选择开关,去选择到底是打开2.4G还是5G:
-
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
-
index 18bf838..857fff4 100644
-
--- a/services/core/java/com/android/server/NetworkManagementService.java
-
+++ b/services/core/java/com/android/server/NetworkManagementService.java
-
@@ -1365,10 +1365,29 @@ public class NetworkManagementService extends INetworkManagementService.Stub
-
if (wifiConfig == null) {
-
mConnector.execute("softap", "set", wlanIface);
-
} else {
-
- mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID,
-
+ //add by louhn
-
+ if(wifiConfig.apBand == 0)//AP_BAND_2GHZ
-
+ {
-
+ mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID,
-
+ "broadcast", "6", getSecurityType(wifiConfig),
-
+ new SensitiveArg(wifiConfig.preSharedKey));
-
+ Log.e("LOUHN", "wifiConfig.apBand: AP_BAND_2GHZ");
-
+ }
-
+ else if(wifiConfig.apBand == 1)//AP_BAND_5GHZ
-
+ {
-
+ mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID,
-
+ "broadcast", "153", getSecurityType(wifiConfig),
-
+ new SensitiveArg(wifiConfig.preSharedKey));
-
+ Log.e("LOUHN", "wifiConfig.apBand: AP_BAND_5GHZ");
-
+ }
-
+ else
-
+ {
-
+ mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID,
-
"broadcast", "6", getSecurityType(wifiConfig),
-
new SensitiveArg(wifiConfig.preSharedKey));
-
- }
-
+ Log.e("LOUHN", "Don't know wifiConfig.apBand");
-
+ }
-
+ }
-
mConnector.execute("softap", "startap");
-
} catch (NativeDaemonConnectorException e) {
-
throw e.rethrowAsParcelableException();
最终编译烧写验证,该2.4G/5G开关生效。