【安卓Framework学习】Wifi框架学习之热点评分机制

系列文章目录

【安卓Framework学习】Wifi框架学习之核心类
【安卓Framework学习】Wifi框架学习之wifi状态机
【安卓Framework学习】Wifi框架学习之连接与断开流程
【安卓Framework学习】Wifi框架学习之扫描模式及扫描流程.
【安卓Framework学习】Wifi框架学习之开启与关闭流程.
【安卓Framework学习】安卓连接管理(ConnectivityService)之wifi连接及注册.



前言

之前分析过wifi框架中的连接断开、开启关闭以及扫描相关的流程,本篇将继续分析wifi框架中隐藏较深的一个机制——热点的评分机制。在安卓wifi框架中,这一套机制实现了对设备周围的热点在一定规则下进行打分,然后根据分数高低决定是否需要连接。由于此机制中包含的规则较多,如有不正确之处望大家及时指出。文中出现的代码大部分基于android11源码。


一、如何触发评分机制

1、回调注册源码分析

【安卓Framework学习】Wifi框架学习之开启与关闭流程.中wifi开启后ClientModeImpl会进入到ConnectModeState中,看看ConnectModeState.enter()做了啥。

	public void enter() {
   
   
	    /*省略部分代码*/
	    mWifiConnectivityManager.setWifiEnabled(true);
	    mNetworkFactory.setWifiState(true);
	    /*省略部分代码*/
	}

进入状态的方法中调用了WifiConnectivityManager.setWifiEnabled()方法,在看其中实现了什么内容。

	public void setWifiEnabled(boolean enable) {
   
   
	   /*省略部分代码*/
	    mWifiEnabled = enable;
	    updateRunningState();
	}

会调用到内部私有方法updateRunningState()中,这个方法内部较为简单,这里假定是已经设置了需要自动连接的情况下,会继续进入到start()方法中,如下。

	private void start() {
   
   
	    if (mRunning) return;
	    retrieveWifiScanner();
	    /*省略部分代码*/
	}

retrieveWifiScanner()方法中,想服务端注册了回调类WifiConnectivityManager.AllSingleScanListener

WifiConnectivityManager.java
	private void retrieveWifiScanner() {
   
   
	    /*省略部分代码*/
	    mScanner.registerScanListener(new HandlerExecutor(mEventHandler), mAllSingleScanListener);
	}
	
WifiScanner.java
	public void registerScanListener(@NonNull @CallbackExecutor Executor executor,
	        @NonNull ScanListener listener) {
   
   
	    /*省略部分代码*/
	    int key = addListener(listener, executor);
	    if (key == INVALID_KEY) return;
	    validateChannel();
	    mAsyncChannel.sendMessage(CMD_REGISTER_SCAN_LISTENER, 0, key);
	}

调用了WifiScanner.registerScanListener()方法,在WifiScanner中又通过异步通信将回调注册到WifiScanningServiceImpl中,回调注册就到这结束了。更详细的回调注册和调用在【安卓Framework学习】Wifi框架学习之扫描模式及扫描流程中已经详细说明了,后面开始自动评分也是从回调方法中开始。

2、回调注册流程图

请添加图片描述

二、wifi评分机制流程

1、评分机制源码分析

由上小结可以看出,在扫描结束后会通过调用注册的AllSingleScanListener回调类的onResults()方法,将扫描结果往上传给应用层,AllSingleScanListener.onResults()方法如下。

	public void onResults(WifiScanner.ScanData[] results) {
   
   
	    if (!mWifiEnabled || !mAutoJoinEnabled) {
   
   
	        clearScanDetails();
	        mWaitForFullBandScanResults = false;
	        return;
	    }
	    /*省略部分代码*/
	    boolean wasConnectAttempted = handleScanResults(mScanDetails,
	            ALL_SINGLE_SCAN_LISTENER, isFullBandScanResults);
	    clearScanDetails();
	    /*省略部分代码*/
	}

在调用回调方法时,首先会去判断是否已经打开wifi和是否支持自动连接,如果其中一个条件不满足都不会进行接下来的自动连接操作。这里认定开启了wifi并且支持自动连接,那么接下来将会调用handleScanResults()方法。

	private boolean handleScanResults(List<ScanDetail> scanDetails, String listenerName,
	        boolean isFullScan) {
   
   
	     /*省略部分代码*/
	     /*热点筛选*/
	    List<WifiCandidates.Candidate> candidates = mNetworkSelector.getCandidatesFromScan(
	            scanDetails, bssidBlocklist, mWifiInfo, mStateMachine.isConnected(),
	            mStateMachine.isDisconnected(), mUntrustedConnectionAllowed);
	    mLatestCandidates = candidates;
	    mLatestCandidatesTimestampMs = mClock.getElapsedSinceBootMillis();
	    if (mDeviceMobilityState == WifiManager.DEVICE_MOBILITY_STATE_HIGH_MVMT
	            && mContext.getResources().getBoolean(
	                    R.bool.config_wifiHighMovementNetworkSelectionOptimizationEnabled)) {
   
   
	        candidates = filterCandidatesHighMovement(candidates, listenerName, isFullScan);
	    }
	    
	    /*热点评分优选*/
	    WifiConfiguration candidate = mNetworkSelector.selectNetwork(candidates);
	    mLastNetworkSelectionTimeStamp = mClock.getElapsedSinceBootMillis();
	    mWifiLastResortWatchdog.updateAvailableNetworks(
	            mNetworkSelector.getConnectableScanDetails());
	    mWifiMetrics.countScanResults(scanDetails);
	    if (candidate != null) {
   
   
	    	/*热点连接*/
	        localLog(listenerName + ":  WNS candidate-" + candidate.SSID);
	        connectToNetwork(candidate);
	        return true;
	    } else {
   
   
	        /*省略部分代码*/
	    }
	}

此方法包含了热点筛选、热点评分以及连接优选出来的热点等核心过程。其中热点筛选主要是通过wifi网络选择器WifiNetworkSelector中的getCandidatesFromScan()方法选择出候选热点列表。

	public List<WifiCandidates.Candidate> getCandidatesFromScan(
	        List<ScanDetail> scanDetails, Set<String> bssidBlacklist, WifiInfo wifiInfo,
	        boolean connected, boolean disconnected, boolean untrustedNetworkAllowed) 
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值