Platform: Rockchip OS: Android 6.0 Kernel: 3.10.92
概念: PNO 即Preferred Network Offload,用于系统在休眠的时候连接WiFi 此功能是在Android3.1加入的
缺陷: 在使用PNO时,有潜在泄露个人隐私的风险。这里没明白,意思是说PNO会发送之前的连接过的网络给AP,然后hacker截取?
代码: 当屏幕状态有变化的时候,会调用handleScreenStateChanged(),如果pno功能有enable,就会配置pno,然后再scan.
private void handleScreenStateChanged(boolean screenOn) { //亮屏的情况 if (screenOn) { enableBackgroundScan(false); setScanAlarm(false); clearBlacklist(); fullBandConnectedTimeIntervalMilli = mWifiConfigStore.wifiAssociatedShortScanIntervalMilli.get(); // In either Disconnectedstate or ConnectedState, // start the scan alarm so as to enable autojoin //如果当前是连接着的 if (getCurrentState() == mConnectedState && allowFullBandScanAndAssociated()) { //PNO功能是否开启了 if (useHalBasedAutoJoinOffload()) { //使用PNO来扫描 startGScanConnectedModeOffload("screenOnConnected"); } else { // Scan after 500ms startDelayedScan(500, null, null); } } else if (getCurrentState() == mDisconnectedState) { if (useHalBasedAutoJoinOffload()) { //调用未连接的PNO扫描 startGScanDisconnectedModeOffload("screenOnDisconnected"); } else { // Scan after 500ms startDelayedScan(500, null, null); } } //关屏休眠时 } else { //当处于未连接状态时 if (getCurrentState() == mDisconnectedState) { // Screen Off and Disconnected and chipset doesn't support scan offload // => start scan alarm // Screen Off and Disconnected and chipset does support scan offload // => will use scan offload (i.e. background scan) //如果不支持PNO,那么就用alarm做定期扫描 if (useHalBasedAutoJoinOffload()) { startGScanDisconnectedModeOffload("screenOffDisconnected"); } else { if (!mBackgroundScanSupported) { setScanAlarm(true); } else { if (!mIsScanOngoing) { enableBackgroundScan(true); } } } } else { enableBackgroundScan(false); if (useHalBasedAutoJoinOffload()) { // don't try stop Gscan if it is not enabled stopGScan("ScreenOffStop(enableBackground=" + mLegacyPnoEnabled + ") "); } } } } private boolean startGScanConnectedModeOffload(String reason) { if (!useHalBasedAutoJoinOffload()) return false; //获取pno列表 List<WifiNative.WifiPnoNetwork> llist = mWifiAutoJoinController.getPnoList(getCurrentWifiConfiguration()); // first program the network we want to look for thru the pno API WifiNative.WifiPnoNetwork list[] = (WifiNative.WifiPnoNetwork[]) llist.toArray(new WifiNative.WifiPnoNetwork[0]); //设置pno if (!WifiNative.setPnoList(list, WifiStateMachine.this)) { Log.e(TAG, "Failed to set pno, length = " + list.length); return false; } }pno list的创建在buildPnoList():
private void buildPnoList() { mCachedPnoList = new ArrayList<WifiNative.WifiPnoNetwork>(); ArrayList<WifiConfiguration> sortedWifiConfigurations = new ArrayList<WifiConfiguration>(getConfiguredNetworks()); Log.e(TAG, "buildPnoList sortedWifiConfigurations size " + sortedWifiConfigurations.size()); if (sortedWifiConfigurations.size() != 0) { // Sort by descending priority Collections.sort(sortedWifiConfigurations, new Comparator<WifiConfiguration>() { public int compare(WifiConfiguration a, WifiConfiguration b) { return a.priority - b.priority; } }); } for (WifiConfiguration config : sortedWifiConfigurations) { // Initialize the RSSI threshold with sane value: // Use the 2.4GHz threshold since most WifiConfigurations are dual bands // There is very little penalty with triggering too soon, i.e. if PNO finds a network // that has an RSSI too low for us to attempt joining it. int threshold = thresholdInitialAutoJoinAttemptMin24RSSI.get(); Log.e(TAG, "found sortedWifiConfigurations : " + config.configKey()); WifiNative.WifiPnoNetwork network = mWifiNative.new WifiPnoNetwork(config, threshold); mCachedPnoList.add(network); } }是否使用pno依赖于如下三个变量判断 1. Settings里有没有打开 2. 驱动是否支持 3. HAL层是否打开
boolean useHalBasedAutoJoinOffload() { // all three settings need to be true: // - developper settings switch // - driver support // - config option return mHalBasedPnoEnableInDevSettings && mHalBasedPnoDriverSupported && mWifiConfigStore.enableHalBasedPno.get(); }rk3288默认是关闭的,可以从log中直接看到: WifiStateMachine: Enter ConnectedState mScreenOn=true scanperiod=20000 useGscan=false/false mHalBasedPnoEnableInDevSettings false
参考: How to Lock Down Your Android Wi-Fi Settings to Improve Privacy Honeycomb MR1 Android bug leaks your location via WiFi