Loading core/jni/android_net_wifi_Wifi.cpp +13 −0 Original line number Diff line number Diff line Loading @@ -556,6 +556,18 @@ static jboolean android_net_wifi_setSuspendOptimizationsCommand(JNIEnv* env, job return doBooleanCommand(cmdstr, "OK"); } static void android_net_wifi_enableBackgroundScan(JNIEnv* env, jobject clazz, jboolean enable) { //Note: BGSCAN-START and BGSCAN-STOP are documented in core/res/res/values/config.xml //and will need an update if the names are changed if (enable) { doBooleanCommand("DRIVER BGSCAN-START", "OK"); } else { doBooleanCommand("DRIVER BGSCAN-STOP", "OK"); } } // ---------------------------------------------------------------------------- /* Loading Loading @@ -623,6 +635,7 @@ static JNINativeMethod gWifiMethods[] = { (void*) android_net_wifi_setSuspendOptimizationsCommand}, { "setCountryCodeCommand", "(Ljava/lang/String;)Z", (void*) android_net_wifi_setCountryCodeCommand}, { "enableBackgroundScan", "(Z)V", (void*) android_net_wifi_enableBackgroundScan}, }; int register_android_net_wifi_WifiManager(JNIEnv* env) Loading core/res/res/values/config.xml +7 −0 Original line number Diff line number Diff line Loading @@ -194,6 +194,13 @@ <!-- Boolean indicating whether the wifi chipset has dual frequency band support --> <bool translatable="false" name="config_wifi_dual_band_support">false</bool> <!-- Boolean indicating whether the wifi chipset supports background scanning mechanism. This mechanism allows the host to remain in suspend state and the dongle to actively scan and wake the host when a configured SSID is detected by the dongle. This chipset capability can provide power savings when wifi needs to be always kept on. The driver commands needed to support the feature are BGSCAN-START and BGSCAN-STOP --> <bool translatable="false" name="config_wifi_background_scan_support">false</bool> <!-- Flag indicating whether the keyguard should be bypassed when the slider is open. This can be set or unset depending how easily the slider can be opened (for example, in a pocket or purse). --> Loading services/java/com/android/server/WifiService.java +12 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,9 @@ public class WifiService extends IWifiManager.Stub { private boolean mDeviceIdle; private int mPluggedType; /* Chipset supports background scan */ private final boolean mBackgroundScanSupported; // true if the user enabled Wifi while in airplane mode private AtomicBoolean mAirplaneModeOverwridden = new AtomicBoolean(false); Loading Loading @@ -369,6 +372,9 @@ public class WifiService extends IWifiManager.Stub { Settings.Secure.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY, 900) * 1000l; mNotificationEnabledSettingObserver = new NotificationEnabledSettingObserver(new Handler()); mNotificationEnabledSettingObserver.register(); mBackgroundScanSupported = mContext.getResources().getBoolean( com.android.internal.R.bool.config_wifi_background_scan_support); } /** Loading Loading @@ -900,6 +906,9 @@ public class WifiService extends IWifiManager.Stub { reportStartWorkSource(); evaluateTrafficStatsPolling(); mWifiStateMachine.enableRssiPolling(true); if (mBackgroundScanSupported) { mWifiStateMachine.enableBackgroundScan(false); } mWifiStateMachine.enableAllNetworks(); updateWifiState(); } else if (action.equals(Intent.ACTION_SCREEN_OFF)) { Loading @@ -909,6 +918,9 @@ public class WifiService extends IWifiManager.Stub { mScreenOff = true; evaluateTrafficStatsPolling(); mWifiStateMachine.enableRssiPolling(false); if (mBackgroundScanSupported) { mWifiStateMachine.enableBackgroundScan(true); } /* * Set a timer to put Wi-Fi to sleep, but only if the screen is off * AND the "stay on while plugged in" setting doesn't match the Loading wifi/java/android/net/wifi/WifiNative.java +2 −0 Original line number Diff line number Diff line Loading @@ -170,4 +170,6 @@ public class WifiNative { * @return the event string sent by the supplicant. */ public native static String waitForEvent(); public native static void enableBackgroundScan(boolean enable); } wifi/java/android/net/wifi/WifiStateMachine.java +61 −9 Original line number Diff line number Diff line Loading @@ -112,9 +112,11 @@ public class WifiStateMachine extends HierarchicalStateMachine { private String mLastBssid; private int mLastNetworkId; private boolean mEnableRssiPolling = false; private boolean mEnableBackgroundScan = false; private int mRssiPollToken = 0; private int mReconnectCount = 0; private boolean mIsScanMode = false; private boolean mScanResultIsPending = false; private boolean mBluetoothConnectionActive = false; Loading Loading @@ -300,6 +302,8 @@ public class WifiStateMachine extends HierarchicalStateMachine { static final int CMD_START_WPS = 89; /* Set the frequency band */ static final int CMD_SET_FREQUENCY_BAND = 90; /* Enable background scan for configured networks */ static final int CMD_ENABLE_BACKGROUND_SCAN = 91; /* Commands from/to the SupplicantStateTracker */ /* Reset the supplicant state tracker */ Loading Loading @@ -823,6 +827,10 @@ public class WifiStateMachine extends HierarchicalStateMachine { sendMessage(obtainMessage(CMD_ENABLE_RSSI_POLL, enabled ? 1 : 0, 0)); } public void enableBackgroundScan(boolean enabled) { sendMessage(obtainMessage(CMD_ENABLE_BACKGROUND_SCAN, enabled ? 1 : 0, 0)); } public void enableAllNetworks() { sendMessage(CMD_ENABLE_ALL_NETWORKS); } Loading Loading @@ -1538,6 +1546,9 @@ public class WifiStateMachine extends HierarchicalStateMachine { case CMD_ENABLE_RSSI_POLL: mEnableRssiPolling = (message.arg1 == 1); break; case CMD_ENABLE_BACKGROUND_SCAN: mEnableBackgroundScan = (message.arg1 == 1); break; /* Discard */ case CMD_LOAD_DRIVER: case CMD_UNLOAD_DRIVER: Loading Loading @@ -1973,6 +1984,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { eventLoggingEnabled = false; setScanResults(WifiNative.scanResultsCommand()); sendScanResultsAvailableBroadcast(); mScanResultIsPending = false; break; case CMD_PING_SUPPLICANT: boolean ok = WifiNative.pingCommand(); Loading Loading @@ -2180,6 +2192,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { case CMD_START_SCAN: eventLoggingEnabled = false; WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE); mScanResultIsPending = true; break; case CMD_SET_HIGH_PERF_MODE: setHighPerfModeEnabledNative(message.arg1 == 1); Loading Loading @@ -2681,8 +2694,8 @@ public class WifiStateMachine extends HierarchicalStateMachine { * back to CONNECT_MODE. */ WifiNative.setScanResultHandlingCommand(SCAN_ONLY_MODE); WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE); break; /* Have the parent state handle the rest */ return NOT_HANDLED; /* Ignore connection to same network */ case CMD_CONNECT_NETWORK: int netId = message.arg1; Loading Loading @@ -2771,21 +2784,35 @@ public class WifiStateMachine extends HierarchicalStateMachine { } class DisconnectedState extends HierarchicalState { private boolean mAlarmEnabled = false; @Override public void enter() { if (DBG) Log.d(TAG, getName() + "\n"); EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName()); /** * In a disconnected state, an infrequent scan that wakes * up the device is needed to ensure a user connects to * an access point on the move /* * We initiate background scanning if it is enabled, otherwise we * initiate an infrequent scan that wakes up the device to ensure * a user connects to an access point on the move */ if (mEnableBackgroundScan) { /* If a regular scan result is pending, do not initiate background * scan until the scan results are returned. This is needed because * initiating a background scan will cancel the regular scan and * scan results will not be returned until background scanning is * cleared */ if (!mScanResultIsPending) { WifiNative.enableBackgroundScan(true); } } else { long scanMs = Settings.Secure.getLong(mContext.getContentResolver(), Settings.Secure.WIFI_SCAN_INTERVAL_MS, DEFAULT_SCAN_INTERVAL_MS); mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + scanMs, scanMs, mScanIntent); mAlarmEnabled = true; } } @Override public boolean processMessage(Message message) { Loading @@ -2800,6 +2827,10 @@ public class WifiStateMachine extends HierarchicalStateMachine { transitionTo(mScanModeState); } break; case CMD_ENABLE_BACKGROUND_SCAN: mEnableBackgroundScan = (message.arg1 == 1); WifiNative.enableBackgroundScan(mEnableBackgroundScan); break; /* Ignore network disconnect */ case NETWORK_DISCONNECTION_EVENT: break; Loading @@ -2808,6 +2839,20 @@ public class WifiStateMachine extends HierarchicalStateMachine { setNetworkDetailedState(WifiInfo.getDetailedStateOf(stateChangeResult.state)); /* DriverStartedState does the rest of the handling */ return NOT_HANDLED; case CMD_START_SCAN: /* Disable background scan temporarily during a regular scan */ if (mEnableBackgroundScan) { WifiNative.enableBackgroundScan(false); } /* Handled in parent state */ return NOT_HANDLED; case SCAN_RESULTS_EVENT: /* Re-enable background scan when a pending scan result is received */ if (mEnableBackgroundScan && mScanResultIsPending) { WifiNative.enableBackgroundScan(true); } /* Handled in parent state */ return NOT_HANDLED; default: return NOT_HANDLED; } Loading @@ -2817,7 +2862,14 @@ public class WifiStateMachine extends HierarchicalStateMachine { @Override public void exit() { /* No need for a background scan upon exit from a disconnected state */ if (mEnableBackgroundScan) { WifiNative.enableBackgroundScan(false); } if (mAlarmEnabled) { mAlarmManager.cancel(mScanIntent); mAlarmEnabled = false; } } } Loading Loading
core/jni/android_net_wifi_Wifi.cpp +13 −0 Original line number Diff line number Diff line Loading @@ -556,6 +556,18 @@ static jboolean android_net_wifi_setSuspendOptimizationsCommand(JNIEnv* env, job return doBooleanCommand(cmdstr, "OK"); } static void android_net_wifi_enableBackgroundScan(JNIEnv* env, jobject clazz, jboolean enable) { //Note: BGSCAN-START and BGSCAN-STOP are documented in core/res/res/values/config.xml //and will need an update if the names are changed if (enable) { doBooleanCommand("DRIVER BGSCAN-START", "OK"); } else { doBooleanCommand("DRIVER BGSCAN-STOP", "OK"); } } // ---------------------------------------------------------------------------- /* Loading Loading @@ -623,6 +635,7 @@ static JNINativeMethod gWifiMethods[] = { (void*) android_net_wifi_setSuspendOptimizationsCommand}, { "setCountryCodeCommand", "(Ljava/lang/String;)Z", (void*) android_net_wifi_setCountryCodeCommand}, { "enableBackgroundScan", "(Z)V", (void*) android_net_wifi_enableBackgroundScan}, }; int register_android_net_wifi_WifiManager(JNIEnv* env) Loading
core/res/res/values/config.xml +7 −0 Original line number Diff line number Diff line Loading @@ -194,6 +194,13 @@ <!-- Boolean indicating whether the wifi chipset has dual frequency band support --> <bool translatable="false" name="config_wifi_dual_band_support">false</bool> <!-- Boolean indicating whether the wifi chipset supports background scanning mechanism. This mechanism allows the host to remain in suspend state and the dongle to actively scan and wake the host when a configured SSID is detected by the dongle. This chipset capability can provide power savings when wifi needs to be always kept on. The driver commands needed to support the feature are BGSCAN-START and BGSCAN-STOP --> <bool translatable="false" name="config_wifi_background_scan_support">false</bool> <!-- Flag indicating whether the keyguard should be bypassed when the slider is open. This can be set or unset depending how easily the slider can be opened (for example, in a pocket or purse). --> Loading
services/java/com/android/server/WifiService.java +12 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,9 @@ public class WifiService extends IWifiManager.Stub { private boolean mDeviceIdle; private int mPluggedType; /* Chipset supports background scan */ private final boolean mBackgroundScanSupported; // true if the user enabled Wifi while in airplane mode private AtomicBoolean mAirplaneModeOverwridden = new AtomicBoolean(false); Loading Loading @@ -369,6 +372,9 @@ public class WifiService extends IWifiManager.Stub { Settings.Secure.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY, 900) * 1000l; mNotificationEnabledSettingObserver = new NotificationEnabledSettingObserver(new Handler()); mNotificationEnabledSettingObserver.register(); mBackgroundScanSupported = mContext.getResources().getBoolean( com.android.internal.R.bool.config_wifi_background_scan_support); } /** Loading Loading @@ -900,6 +906,9 @@ public class WifiService extends IWifiManager.Stub { reportStartWorkSource(); evaluateTrafficStatsPolling(); mWifiStateMachine.enableRssiPolling(true); if (mBackgroundScanSupported) { mWifiStateMachine.enableBackgroundScan(false); } mWifiStateMachine.enableAllNetworks(); updateWifiState(); } else if (action.equals(Intent.ACTION_SCREEN_OFF)) { Loading @@ -909,6 +918,9 @@ public class WifiService extends IWifiManager.Stub { mScreenOff = true; evaluateTrafficStatsPolling(); mWifiStateMachine.enableRssiPolling(false); if (mBackgroundScanSupported) { mWifiStateMachine.enableBackgroundScan(true); } /* * Set a timer to put Wi-Fi to sleep, but only if the screen is off * AND the "stay on while plugged in" setting doesn't match the Loading
wifi/java/android/net/wifi/WifiNative.java +2 −0 Original line number Diff line number Diff line Loading @@ -170,4 +170,6 @@ public class WifiNative { * @return the event string sent by the supplicant. */ public native static String waitForEvent(); public native static void enableBackgroundScan(boolean enable); }
wifi/java/android/net/wifi/WifiStateMachine.java +61 −9 Original line number Diff line number Diff line Loading @@ -112,9 +112,11 @@ public class WifiStateMachine extends HierarchicalStateMachine { private String mLastBssid; private int mLastNetworkId; private boolean mEnableRssiPolling = false; private boolean mEnableBackgroundScan = false; private int mRssiPollToken = 0; private int mReconnectCount = 0; private boolean mIsScanMode = false; private boolean mScanResultIsPending = false; private boolean mBluetoothConnectionActive = false; Loading Loading @@ -300,6 +302,8 @@ public class WifiStateMachine extends HierarchicalStateMachine { static final int CMD_START_WPS = 89; /* Set the frequency band */ static final int CMD_SET_FREQUENCY_BAND = 90; /* Enable background scan for configured networks */ static final int CMD_ENABLE_BACKGROUND_SCAN = 91; /* Commands from/to the SupplicantStateTracker */ /* Reset the supplicant state tracker */ Loading Loading @@ -823,6 +827,10 @@ public class WifiStateMachine extends HierarchicalStateMachine { sendMessage(obtainMessage(CMD_ENABLE_RSSI_POLL, enabled ? 1 : 0, 0)); } public void enableBackgroundScan(boolean enabled) { sendMessage(obtainMessage(CMD_ENABLE_BACKGROUND_SCAN, enabled ? 1 : 0, 0)); } public void enableAllNetworks() { sendMessage(CMD_ENABLE_ALL_NETWORKS); } Loading Loading @@ -1538,6 +1546,9 @@ public class WifiStateMachine extends HierarchicalStateMachine { case CMD_ENABLE_RSSI_POLL: mEnableRssiPolling = (message.arg1 == 1); break; case CMD_ENABLE_BACKGROUND_SCAN: mEnableBackgroundScan = (message.arg1 == 1); break; /* Discard */ case CMD_LOAD_DRIVER: case CMD_UNLOAD_DRIVER: Loading Loading @@ -1973,6 +1984,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { eventLoggingEnabled = false; setScanResults(WifiNative.scanResultsCommand()); sendScanResultsAvailableBroadcast(); mScanResultIsPending = false; break; case CMD_PING_SUPPLICANT: boolean ok = WifiNative.pingCommand(); Loading Loading @@ -2180,6 +2192,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { case CMD_START_SCAN: eventLoggingEnabled = false; WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE); mScanResultIsPending = true; break; case CMD_SET_HIGH_PERF_MODE: setHighPerfModeEnabledNative(message.arg1 == 1); Loading Loading @@ -2681,8 +2694,8 @@ public class WifiStateMachine extends HierarchicalStateMachine { * back to CONNECT_MODE. */ WifiNative.setScanResultHandlingCommand(SCAN_ONLY_MODE); WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE); break; /* Have the parent state handle the rest */ return NOT_HANDLED; /* Ignore connection to same network */ case CMD_CONNECT_NETWORK: int netId = message.arg1; Loading Loading @@ -2771,21 +2784,35 @@ public class WifiStateMachine extends HierarchicalStateMachine { } class DisconnectedState extends HierarchicalState { private boolean mAlarmEnabled = false; @Override public void enter() { if (DBG) Log.d(TAG, getName() + "\n"); EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName()); /** * In a disconnected state, an infrequent scan that wakes * up the device is needed to ensure a user connects to * an access point on the move /* * We initiate background scanning if it is enabled, otherwise we * initiate an infrequent scan that wakes up the device to ensure * a user connects to an access point on the move */ if (mEnableBackgroundScan) { /* If a regular scan result is pending, do not initiate background * scan until the scan results are returned. This is needed because * initiating a background scan will cancel the regular scan and * scan results will not be returned until background scanning is * cleared */ if (!mScanResultIsPending) { WifiNative.enableBackgroundScan(true); } } else { long scanMs = Settings.Secure.getLong(mContext.getContentResolver(), Settings.Secure.WIFI_SCAN_INTERVAL_MS, DEFAULT_SCAN_INTERVAL_MS); mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + scanMs, scanMs, mScanIntent); mAlarmEnabled = true; } } @Override public boolean processMessage(Message message) { Loading @@ -2800,6 +2827,10 @@ public class WifiStateMachine extends HierarchicalStateMachine { transitionTo(mScanModeState); } break; case CMD_ENABLE_BACKGROUND_SCAN: mEnableBackgroundScan = (message.arg1 == 1); WifiNative.enableBackgroundScan(mEnableBackgroundScan); break; /* Ignore network disconnect */ case NETWORK_DISCONNECTION_EVENT: break; Loading @@ -2808,6 +2839,20 @@ public class WifiStateMachine extends HierarchicalStateMachine { setNetworkDetailedState(WifiInfo.getDetailedStateOf(stateChangeResult.state)); /* DriverStartedState does the rest of the handling */ return NOT_HANDLED; case CMD_START_SCAN: /* Disable background scan temporarily during a regular scan */ if (mEnableBackgroundScan) { WifiNative.enableBackgroundScan(false); } /* Handled in parent state */ return NOT_HANDLED; case SCAN_RESULTS_EVENT: /* Re-enable background scan when a pending scan result is received */ if (mEnableBackgroundScan && mScanResultIsPending) { WifiNative.enableBackgroundScan(true); } /* Handled in parent state */ return NOT_HANDLED; default: return NOT_HANDLED; } Loading @@ -2817,7 +2862,14 @@ public class WifiStateMachine extends HierarchicalStateMachine { @Override public void exit() { /* No need for a background scan upon exit from a disconnected state */ if (mEnableBackgroundScan) { WifiNative.enableBackgroundScan(false); } if (mAlarmEnabled) { mAlarmManager.cancel(mScanIntent); mAlarmEnabled = false; } } } Loading