OSDN Git Service

Merge "Start using NetworkUtils.numericToInetAddress."
[android-x86/frameworks-base.git] / wifi / java / android / net / wifi / WifiStateMachine.java
index b21f025..e89858c 100644 (file)
@@ -59,6 +59,7 @@ import android.os.Binder;
 import android.os.IBinder;
 import android.os.INetworkManagementService;
 import android.os.Message;
+import android.os.Messenger;
 import android.os.PowerManager;
 import android.os.Process;
 import android.os.RemoteException;
@@ -112,9 +113,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;
 
@@ -300,6 +303,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 */
@@ -801,28 +806,20 @@ public class WifiStateMachine extends HierarchicalStateMachine {
         sendMessage(obtainMessage(CMD_FORGET_NETWORK, netId, 0));
     }
 
-    public WpsResult startWps(AsyncChannel channel, WpsConfiguration config) {
-        WpsResult result;
-        switch (config.setup) {
-            case PIN_FROM_DEVICE:
-            case PBC:
-            case PIN_FROM_ACCESS_POINT:
-                //TODO: will go away with AsyncChannel use from settings
-                Message resultMsg = channel.sendMessageSynchronously(CMD_START_WPS, config);
-                result = (WpsResult) resultMsg.obj;
-                resultMsg.recycle();
-                break;
-            default:
-                result = new WpsResult(Status.FAILURE);
-                break;
-        }
-        return result;
+    public void startWps(Messenger replyTo, WpsConfiguration config) {
+        Message msg = obtainMessage(CMD_START_WPS, config);
+        msg.replyTo = replyTo;
+        sendMessage(msg);
     }
 
     public void enableRssiPolling(boolean enabled) {
        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);
     }
@@ -1539,6 +1536,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:
@@ -1578,7 +1578,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
                     break;
                 case CMD_START_WPS:
                     /* Return failure when the state machine cannot handle WPS initiation*/
-                    mReplyChannel.replyToMessage(message, message.what,
+                    mReplyChannel.replyToMessage(message, WifiManager.CMD_WPS_COMPLETED,
                                 new WpsResult(Status.FAILURE));
                     break;
                 default:
@@ -1974,6 +1974,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
                     eventLoggingEnabled = false;
                     setScanResults(WifiNative.scanResultsCommand());
                     sendScanResultsAvailableBroadcast();
+                    mScanResultIsPending = false;
                     break;
                 case CMD_PING_SUPPLICANT:
                     boolean ok = WifiNative.pingCommand();
@@ -2181,6 +2182,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);
@@ -2682,8 +2684,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;
@@ -2772,21 +2774,49 @@ public class WifiStateMachine extends HierarchicalStateMachine {
     }
 
     class DisconnectedState extends HierarchicalState {
+        private boolean mAlarmEnabled = false;
+        private long mScanIntervalMs;
+
+        private void setScanAlarm(boolean enabled) {
+            if (enabled == mAlarmEnabled) return;
+            if (enabled) {
+                mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
+                        System.currentTimeMillis() + mScanIntervalMs,
+                        mScanIntervalMs,
+                        mScanIntent);
+
+                mAlarmEnabled = true;
+            } else {
+                mAlarmManager.cancel(mScanIntent);
+                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
-             */
-            long scanMs = Settings.Secure.getLong(mContext.getContentResolver(),
+            mScanIntervalMs = 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);
+            /*
+             * 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 {
+                setScanAlarm(true);
+            }
         }
         @Override
         public boolean processMessage(Message message) {
@@ -2801,6 +2831,16 @@ public class WifiStateMachine extends HierarchicalStateMachine {
                         transitionTo(mScanModeState);
                     }
                     break;
+                case CMD_ENABLE_BACKGROUND_SCAN:
+                    mEnableBackgroundScan = (message.arg1 == 1);
+                    if (mEnableBackgroundScan) {
+                        WifiNative.enableBackgroundScan(true);
+                        setScanAlarm(false);
+                    } else {
+                        WifiNative.enableBackgroundScan(false);
+                        setScanAlarm(true);
+                    }
+                    break;
                     /* Ignore network disconnect */
                 case NETWORK_DISCONNECTION_EVENT:
                     break;
@@ -2809,6 +2849,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;
             }
@@ -2818,7 +2872,11 @@ public class WifiStateMachine extends HierarchicalStateMachine {
 
         @Override
         public void exit() {
-            mAlarmManager.cancel(mScanIntent);
+            /* No need for a background scan upon exit from a disconnected state */
+            if (mEnableBackgroundScan) {
+                WifiNative.enableBackgroundScan(false);
+            }
+            setScanAlarm(false);
         }
     }