Android N wifi
Android N 的wifi架构真的是改动挺大,从文件目录看,添加了不少文件,实际上则是对整个wifi模块进行大卸耦,很多东西被才成独立的模块,便于维护,添加feature,这里貌似采用了门面设计模式,可以看FrameworkFacade.java,。下面就看下android N wifi scan都做了哪些修改。
startScan
startScan的API没有做什么变化,也是从wifiManager一直call到WIFiStateMachine里面。
但是在WiFiStatemachine中处理CMD_START_SCAN这里就开始发生变化了。从handleScanRequest
开始看吧
/*WifiStateMachine.java (frameworks\opt\net\wifi\service\java\com\android\server\wifi)
*/
private void handleScanRequest(Message message) {
ScanSettings settings = null;
WorkSource workSource = null;
// unbundle parameters
Bundle bundle = (Bundle) message.obj;
if (bundle != null) {
settings = bundle.getParcelable(CUSTOMIZED_SCAN_SETTING);
workSource = bundle.getParcelable(CUSTOMIZED_SCAN_WORKSOURCE);
}
Set<Integer> freqs = null;
//setting里面记录了fred的信息
if (settings != null && settings.channelSet != null) {
freqs = new HashSet<Integer>();
for (WifiChannel channel : settings.channelSet) {
freqs.add(channel.freqMHz);
}
}
// Retrieve the list of hidden networkId's to scan for.
Set<Integer> hiddenNetworkIds = mWifiConfigManager.getHiddenConfiguredNetworkIds();
// call wifi native to start the scan
//这里是重点
if (startScanNative(freqs, hiddenNetworkIds, workSource)) {
// a full scan covers everything, clearing scan request buffer
if (freqs == null)
mBufferedScanMsg.clear();
messageHandlingStatus = MESSAGE_HANDLING_STATUS_OK;
if (workSource != null) {
// External worksource was passed along the scan request,
// hence always send a broadcast
mSendScanResultsBroadcast = true;
}
return;
}
// if reach here, scan request is rejected
.....
}
看下这个startScanNative
都做了些什么,其实这个函数起了一个wifiScanner和WifiStatemachine之间的桥梁作用。
// TODO this is a temporary measure to bridge between WifiScanner and WifiStateMachine until
// scan functionality is refactored out of WifiStateMachine.
/**
* return true iff scan request is accepted
*/
private boolean startScanNative(final Set<Integer> freqs, Set<Integer> hiddenNetworkIds,
WorkSource workSource) {
//创建了一个ScanSetting对象,目的是为了设置scan的频率模式
WifiScanner.ScanSettings settings = new WifiScanner.ScanSettings();
if (freqs == null) {
/*假如我们前面没有指定freqs是什么,这里默认会采用WIFI_BAND_BOTH_WITH_DFS
Both 2.4 GHz band and 5 GHz band; with DFS channels
public static final int WIFI_BAND_BOTH_WITH_DFS = 7;
both bands with DFS channels
*/
settings.band = WifiScanner.WIFI_BAND_BOTH_WITH_DFS;
} else {
settings.band = WifiScanner.WIFI_BAND_UNSPECIFIED;
int index = 0;
settings.channels = new WifiScanner.ChannelSpec[freqs.size()];
for (Integer freq : freqs) {
settings.channels[index++] = new WifiScanner.ChannelSpec(freq);
}
}
settings.reportEvents = WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN
| WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT;
if (hiddenNetworkIds != null && hiddenNetworkIds.size() > 0) {
int i = 0;
settings.hiddenNetworkIds = new int[hiddenNetworkIds.size()];
for (Integer netId : hiddenNetworkIds) {
settings.hiddenNetworkIds[i++] = netId;
}
}
//创建一个监听对象,这个后面调用mWifiScanner.startScan会用到
WifiScanner.ScanListener nativeScanListener = new WifiScanner.ScanListener() {
// ignore all events since WifiStateMachine is registered for the supplicant events
public void onSuccess() {
}
public void onFailure(int reason, String description) {
mIsScanOngoing = false;
mIsFullScanOngoing = false;
}
public void onResults(WifiScanner.ScanData[] results) {
}
public void onFullResult(ScanResult fullScanResult) {
}
public void onPeriodChanged(int periodInMs) {
}
};
//跳转到mWifiScanner.startScan()
mWifiScanner.startScan(settings, nativeScanListener, workSource);
mIsScanOngoing = true;
mIsFullScanOngoing = (freqs == null);
lastScanFreqs = freqs;
return true;
}
wifiScann是android N新添加进来的东西,其实这个一个client端。在android N,wifi scan被做成一个独立的service。这边是client端,通过asynchannel会发送CMD去service端,跑真正的scan函数。
//WifiScanner.java (frameworks\base\wifi\java\android\net\wifi)
/**
* starts a single scan and reports results asynchronously
* @param settings specifies various parame