通常,我们在设备开启Wifi之后,等会儿自动扫描出周围的热点,
注意此时我们并没有点击扫描键,只是点击了一下wifi 开关就可以完成两件事情(1. 开启wifi,2. 扫描周围热点),
问题,第二点是如何实现的呢?
请详看本文 ~~
以下的代码流程,在Android P WiFi Enable 流程基础上往下继续
frameworks/opt/net/wifi/service/java/com/android/server/wifi/ClientModeManager.java
public boolean processMessage(Message message) {
....
mClientInterfaceName = mWifiNative.setupInterfaceForClientMode
....
transitionTo(mStartedState); //跳转到 StartedState
}
private class StartedState extends State {
...
private void onUpChanged(boolean isUp) {
....
sendScanAvailableBroadcast(true);
mWifiStateMachine.setOperationalMode(WifiStateMachine.CONNECT_MODE,
// 发 WifiManager.WIFI_STATE_CHANGED_ACTION 广播通知 wifiTracker 启动startScan
updateWifiState(WifiManager.WIFI_STATE_ENABLED,WifiManager.WIFI_STATE_ENABLING);
}
}
frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
public void onReceive(Context context, Intent intent) {
if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action))
{
updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,WifiManager.WIFI_STATE_UNKNOWN));
}
}
private void updateWifiState(int state) {
1. WifiManager.WIFI_STATE_ENABLED
mScanner.resume();
2.wifi 非enabled 则 mScanner.pause();
}
public void handleMessage(Message message) {
..
mWifiManager.startScan(); // 开启Wifi Scan
}
frameworks/opt/net/wifi/service/java/com/android/server/wifi/ScanRequestProxy.java
public boolean startScan(int callingUid, String packageName){
retrieveWifiScannerIfNecessary();
...
// Create a worksource using the caller's UID.
WorkSource workSource = new WorkSource(callingUid);
// Create the scan settings.
WifiScanner.ScanSettings settings = new WifiScanner.ScanSettings();
// always do full scans
settings.band = WifiScanner.WIFI_BAND_BOTH_WITH_DFS;
settings.reportEvents = WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN
| WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT;
mWifiScanner.startScan(settings, new ScanRequestProxyScanListener(), workSource);
}
frameworks/base/wifi/java/android/net/wifi/WifiScanner.java
public void startScan(ScanSettings settings, ScanListener listener, WorkSource workSource) {
scanParams.putParcelable(SCAN_PARAMS_SCAN_SETTINGS_KEY, settings);
scanParams.putParcelable(SCAN_PARAMS_WORK_SOURCE_KEY, workSource);
mAsyncChannel.sendMessage(CMD_START_SINGLE_SCAN, 0, key, scanParams);
}
frameworks/opt/net/wifi/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
class DriverStartedState extends State {
case WifiScanner.CMD_START_SINGLE_SCAN:
.... 一大堆code (其实就干了几件事情,见上面描述)
....
tryToStartNewScan();
}
frameworks/opt/net/wifi/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
void tryToStartNewScan() {
....
mScannerImpl.startSingleScan(settings, this);
}
frameworks/opt/net/wifi/service/java/com/android/server/wifi/scanner/WifiScannerImpl.java
public abstract boolean startSingleScan(WifiNative.ScanSettings settings,WifiNative.ScanEventHandler eventHandler);
frameworks/opt/net/wifi/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java
public boolean startSingleScan(WifiNative.ScanSettings settings, WifiNative.ScanEventHandler eventHandler) {
....
freqs = allFreqs.getScanFreqs();
success = mWifiNative.scan(mIfaceName, settings.scanType, freqs, hiddenNetworkSSIDSet);
}
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java
public boolean scan( @NonNull String ifaceName, int scanType, Set freqs, Set hiddenNetworkSSIDs) {
mWificondControl.scan(ifaceName, scanType, freqs, hiddenNetworkSSIDs);
}
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WificondControl.java
public boolean scan(@NonNull String ifaceName, int scanType, Set freqs,Set hiddenNetworkSSIDs)
{
..
scannerImpl.scan(settings);
}
system/connectivity/wificond/scanning/scanner_impl.cpp
Status ScannerImpl::scan(const SingleScanSettings& scan_settings, bool* out_success) {
scan_utils_->Scan(interface_index_, request_random_mac, scan_type,ssids, freqs, &error_code); //
}
system/connectivity/wificond/scanning/scan_utils.cpp
bool ScanUtils::Scan(uint32_t interface_index,
bool request_random_mac,
int scan_type,
const vector>& ssids,
const vector& freqs,
int* error_code) {
NL80211Packet trigger_scan(
netlink_manager_->GetFamilyId(),
NL80211_CMD_TRIGGER_SCAN,
netlink_manager_->GetSequenceNumber(),
getpid());
if (scan_flags) {
trigger_scan.AddAttribute(
NL80211Attr(NL80211_ATTR_SCAN_FLAGS,
scan_flags));
}
// We are receiving an ERROR/ACK message instead of the actual
// scan results here, so it is OK to expect a timely response because
// kernel is supposed to send the ERROR/ACK back before the scan starts.
vector> response;
if (!netlink_manager_->SendMessageAndGetAckOrError(trigger_scan,
error_code)) {
// Logging is done inside |SendMessageAndGetAckOrError|.
return false;
}
}