下周三要做内部培训
这里先走读 WakeupController 完成对Android R WIFI重连场景的代码走读覆盖
可以设想这样一种场景:
用户手机wifi关闭,回到家自动打开并连接上家里的wifi
我们把这个流程代码走读一遍
WakeupController
先看注释
/**
* WakeupController is responsible managing Auto Wifi.
*
* <p>It determines if and when to re-enable wifi after it has been turned off by the user.
*/
WakeupController 同样是在 WifiInjector 中被构造
在 ClientModeManager 中有个内部HSM
在进入 ScanOnlyModeState 后,WakeupController.start()
在退出 ScanOnlyModeState 时,WakeupController.stop()
至于 ClientModeManager , 以后再看
static final long LAST_DISCONNECT_TIMEOUT_MILLIS = 5 * 1000;
public void start() {
// 没有高品质网络的话直接 return 掉
if (getGoodSavedNetworksAndSuggestions().isEmpty()) {
return;
}
mWifiInjector.getWifiScanner().registerScanListener(
new HandlerExecutor(mHandler), mScanListener);
setActive(true);
if (isEnabledAndReady()) {
mWakeupOnboarding.maybeShowNotification();
List<ScanResult> scanResults =
filterDfsScanResults(mWifiInjector.getWifiScanner().getSingleScanResults());
Set<ScanResultMatchInfo> matchInfos = toMatchInfos(scanResults);
matchInfos.retainAll(getGoodSavedNetworksAndSuggestions());
// 需要保证将上次断开的网络加到 wakeup lock中
// 因为我们不想重连这个网络
// 这里的限制是 5s 内
long now = mClock.getElapsedSinceBootMillis();
if (mLastDisconnectInfo != null && ((now - mLastDisconnectTimestampMillis)
<= LAST_DISCONNECT_TIMEOUT_MILLIS)) {
matchInfos.add(mLastDisconnectInfo);
}
mWakeupLock.setLock(matchInfos);
}
}
handleScreenStateChanged
用户打开手机亮屏
handleScreenStateChanged 在 ClientModeImpl 的 handleScreenStateChanged 被调用
因为收到亮屏广播被调用
/*
* 亮屏时,有 goodNetworks 的话,每隔10s进行一次扫描
* 灭屏时,不进行扫描
*/
public void handleScreenStateChanged(boolean screenOn) {
if(screenOn){
if(mScanThread != null){
mScanThread.interrupt();
}
// 没有 goodNetworks 的话不会进行扫描
Set<ScanResultMatchInfo> goodNetworks = getGoodSavedNetworksAndSuggestions();
if(goodNetworks == null || goodNetworks.size() == 0 ){
Log.d(TAG, "no scan due to no valid saved network");
return;
}
// 每10s进行一次扫描,最多进行进行10次
mScanThread = new Thread(){
@Override
public void run() {
try{
int count = 0;
while(!isInterrupted() && count < 100){
if(count == 0 || count % 10 == 0){
startScheduledScan();
}
Thread.sleep(1_000);
count ++;
}
}
}
};
mScanThread.start();
}else{
stopScheduledScan();
}
}
handleScanResults
/*
* The controller updates the WakeupLock with the incoming scan results
* If WakeupLock is not yet fully initialized, it adds the current scanResults to the lock and returns
* If WakeupLock is initialized but not empty, the controller updates the lock with the current scan
* If it is both initialized and empty, it evaluates scan results for a match with saved networks
* If a match exists, it enables wifi
*/
private void handleScanResults(Collection<ScanResult> scanResults) {
mNumScansHandled++;
// need to show notification here in case user turns phone on while wifi is off
// 弹出一个通知告知用户wifi将自动打开
mWakeupOnboarding.maybeShowNotification();
// filter out unknown networks
Set<ScanResultMatchInfo> goodNetworks = getGoodSavedNetworksAndSuggestions();
Set<ScanResultMatchInfo> matchInfos = toMatchInfos(scanResults);
matchInfos.retainAll(goodNetworks);
mWakeupLock.update(matchInfos);
if (!mWakeupLock.isUnlocked()) {
return;
}
ScanResult network = mWakeupEvaluator.findViableNetwork(scanResults, goodNetworks);
if (network != null) {
enableWifi();
}
}