diff --git a/core/java/com/android/internal/util/Protocol.java b/core/java/com/android/internal/util/Protocol.java
index b754d94..69b80d9 100644
--- a/core/java/com/android/internal/util/Protocol.java
+++ b/core/java/com/android/internal/util/Protocol.java
@@ -40,6 +40,7 @@
 
     /** Non system protocols */
     public static final int BASE_WIFI                                               = 0x00020000;
+    public static final int BASE_WIFI_WATCHDOG                                      = 0x00021000;
     public static final int BASE_DHCP                                               = 0x00030000;
     public static final int BASE_DATA_CONNECTION                                    = 0x00040000;
     public static final int BASE_DATA_CONNECTION_AC                                 = 0x00041000;
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 5f0922e..7112553 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -35,8 +35,8 @@
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiStateMachine;
 import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiWatchdogStateMachine;
 import android.net.wifi.WifiConfiguration.KeyMgmt;
-import android.net.wifi.WifiWatchdogService;
 import android.net.wifi.WpsConfiguration;
 import android.net.wifi.WpsResult;
 import android.net.ConnectivityManager;
@@ -343,7 +343,7 @@
      * Protected by mWifiStateTracker lock.
      */
     private final WorkSource mTmpWorkSource = new WorkSource();
-    private WifiWatchdogService mWifiWatchdogService;
+    private WifiWatchdogStateMachine mWifiWatchdogStateMachine;
 
     WifiService(Context context) {
         mContext = context;
@@ -434,8 +434,9 @@
                 (wifiEnabled ? "enabled" : "disabled"));
         setWifiEnabled(wifiEnabled);
 
-        //TODO: as part of WWS refactor, create only when needed
-        mWifiWatchdogService = new WifiWatchdogService(mContext);
+        mWifiWatchdogStateMachine = WifiWatchdogStateMachine.
+               makeWifiWatchdogStateMachine(mContext);
+
     }
 
     private boolean testAndClearWifiSavedState() {
@@ -1162,8 +1163,8 @@
         mLocks.dump(pw);
 
         pw.println();
-        pw.println("WifiWatchdogService dump");
-        mWifiWatchdogService.dump(pw);
+        pw.println("WifiWatchdogStateMachine dump");
+        mWifiWatchdogStateMachine.dump(pw);
     }
 
     private class WifiLock extends DeathRecipient {
diff --git a/wifi/java/android/net/wifi/WifiWatchdogService.java b/wifi/java/android/net/wifi/WifiWatchdogService.java
deleted file mode 100644
index bce4b3a..0000000
--- a/wifi/java/android/net/wifi/WifiWatchdogService.java
+++ /dev/null
@@ -1,765 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.database.ContentObserver;
-import android.net.ConnectivityManager;
-import android.net.DnsPinger;
-import android.net.NetworkInfo;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.Slog;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintWriter;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Scanner;
-
-/**
- * {@link WifiWatchdogService} monitors the initial connection to a Wi-Fi
- * network with multiple access points. After the framework successfully
- * connects to an access point, the watchdog verifies connectivity by 'pinging'
- * the configured DNS server using {@link DnsPinger}.
- * <p>
- * On DNS check failure, the BSSID is blacklisted if it is reasonably likely
- * that another AP might have internet access; otherwise the SSID is disabled.
- * <p>
- * On DNS success, the WatchdogService initiates a walled garden check via an
- * http get. A browser windows is activated if a walled garden is detected.
- * 
- * @hide
- */
-public class WifiWatchdogService {
-
-    private static final String WWS_TAG = "WifiWatchdogService";
-
-    private static final boolean VDBG = true;
-    private static final boolean DBG = true;
-
-    // Used for verbose logging
-    private String mDNSCheckLogStr;
-
-    private Context mContext;
-    private ContentResolver mContentResolver;
-    private WifiManager mWifiManager;
-
-    private WifiWatchdogHandler mHandler;
-
-    private DnsPinger mDnsPinger;
-
-    private IntentFilter mIntentFilter;
-    private BroadcastReceiver mBroadcastReceiver;
-    private boolean mBroadcastsEnabled;
-
-    private static final int WIFI_SIGNAL_LEVELS = 4;
-
-    /**
-     * Low signal is defined as less than or equal to cut off
-     */
-    private static final int LOW_SIGNAL_CUTOFF = 0;
-
-    private static final long MIN_LOW_SIGNAL_CHECK_INTERVAL = 2 * 60 * 1000;
-    private static final long MIN_SINGLE_DNS_CHECK_INTERVAL = 10 * 60 * 1000;
-    private static final long MIN_WALLED_GARDEN_INTERVAL = 15 * 60 * 1000;
-
-    private static final int MAX_CHECKS_PER_SSID = 9;
-    private static final int NUM_DNS_PINGS = 7;
-    private static double MIN_RESPONSE_RATE = 0.50;
-
-    // TODO : Adjust multiple DNS downward to 250 on repeated failure
-    // private static final int MULTI_DNS_PING_TIMEOUT_MS = 250;
-
-    private static final int DNS_PING_TIMEOUT_MS = 800;
-    private static final long DNS_PING_INTERVAL = 250;
-
-    private static final long BLACKLIST_FOLLOWUP_INTERVAL = 15 * 1000;
-
-    private Status mStatus = new Status();
-
-    private static class Status {
-        String bssid = "";
-        String ssid = "";
-
-        HashSet<String> allBssids = new HashSet<String>();
-        int numFullDNSchecks = 0;
-
-        long lastSingleCheckTime = -24 * 60 * 60 * 1000;
-        long lastWalledGardenCheckTime = -24 * 60 * 60 * 1000;
-
-        WatchdogState state = WatchdogState.INACTIVE;
-
-        // Info for dns check
-        int dnsCheckTries = 0;
-        int dnsCheckSuccesses = 0;
-
-        public int signal = -200;
-
-    }
-
-    private enum WatchdogState {
-        /**
-         * Full DNS check in progress
-         */
-        DNS_FULL_CHECK,
-
-        /**
-         * Walled Garden detected, will pop up browser next round.
-         */
-        WALLED_GARDEN_DETECTED,
-
-        /**
-         * DNS failed, will blacklist/disable AP next round
-         */
-        DNS_CHECK_FAILURE,
-
-        /**
-         * Online or displaying walled garden auth page
-         */
-        CHECKS_COMPLETE,
-
-        /**
-         * Watchdog idle, network has been blacklisted or received disconnect
-         * msg
-         */
-        INACTIVE,
-
-        BLACKLISTED_AP
-    }
-
-    public WifiWatchdogService(Context context) {
-        mContext = context;
-        mContentResolver = context.getContentResolver();
-        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
-        mDnsPinger = new DnsPinger("WifiWatchdogServer.DnsPinger", context,
-                ConnectivityManager.TYPE_WIFI);
-
-        HandlerThread handlerThread = new HandlerThread("WifiWatchdogServiceThread");
-        handlerThread.start();
-        mHandler = new WifiWatchdogHandler(handlerThread.getLooper());
-
-        setupNetworkReceiver();
-
-        // The content observer to listen needs a handler, which createThread
-        // creates
-        registerForSettingsChanges();
-
-        // Start things off
-        if (isWatchdogEnabled()) {
-            mHandler.sendEmptyMessage(WifiWatchdogHandler.MESSAGE_CONTEXT_EVENT);
-        }
-    }
-
-    /**
-     *
-     */
-    private void setupNetworkReceiver() {
-        mBroadcastReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                String action = intent.getAction();
-                if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
-                    mHandler.sendMessage(mHandler.obtainMessage(
-                            WifiWatchdogHandler.MESSAGE_NETWORK_EVENT,
-                            intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO)
-                            ));
-                } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
-                    mHandler.sendEmptyMessage(WifiWatchdogHandler.RSSI_CHANGE_EVENT);
-                } else if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
-                    mHandler.sendEmptyMessage(WifiWatchdogHandler.SCAN_RESULTS_AVAILABLE);
-                } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
-                    mHandler.sendMessage(mHandler.obtainMessage(
-                            WifiWatchdogHandler.WIFI_STATE_CHANGE,
-                            intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 4)));
-                }
-            }
-        };
-
-        mIntentFilter = new IntentFilter();
-        mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
-        mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
-        mIntentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);
-        mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
-    }
-
-    /**
-     * Observes the watchdog on/off setting, and takes action when changed.
-     */
-    private void registerForSettingsChanges() {
-        ContentObserver contentObserver = new ContentObserver(mHandler) {
-            @Override
-            public void onChange(boolean selfChange) {
-                mHandler.sendEmptyMessage((WifiWatchdogHandler.MESSAGE_CONTEXT_EVENT));
-            }
-        };
-
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_ON),
-                false, contentObserver);
-    }
-
-    private void handleNewConnection() {
-        WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
-        String newSsid = wifiInfo.getSSID();
-        String newBssid = wifiInfo.getBSSID();
-
-        if (VDBG) {
-            Slog.v(WWS_TAG, String.format("handleConnected:: old (%s, %s) ==> new (%s, %s)",
-                    mStatus.ssid, mStatus.bssid, newSsid, newBssid));
-        }
-
-        if (TextUtils.isEmpty(newSsid) || TextUtils.isEmpty(newBssid)) {
-            return;
-        }
-
-        if (!TextUtils.equals(mStatus.ssid, newSsid)) {
-            mStatus = new Status();
-            mStatus.ssid = newSsid;
-        }
-
-        mStatus.bssid = newBssid;
-        mStatus.allBssids.add(newBssid);
-        mStatus.signal = WifiManager.calculateSignalLevel(wifiInfo.getRssi(), WIFI_SIGNAL_LEVELS);
-
-        initDnsFullCheck();
-    }
-
-    public void updateRssi() {
-        WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
-        if (!TextUtils.equals(mStatus.ssid, wifiInfo.getSSID()) ||
-                !TextUtils.equals(mStatus.bssid, wifiInfo.getBSSID())) {
-            return;
-        }
-
-        mStatus.signal = WifiManager.calculateSignalLevel(wifiInfo.getRssi(), WIFI_SIGNAL_LEVELS);
-    }
-
-    /**
-     * Single step in state machine
-     */
-    private void handleStateStep() {
-        // Slog.v(WWS_TAG, "handleStateStep:: " + mStatus.state);
-
-        switch (mStatus.state) {
-            case DNS_FULL_CHECK:
-                if (VDBG) {
-                    Slog.v(WWS_TAG, "DNS_FULL_CHECK: " + mDNSCheckLogStr);
-                }
-
-                long pingResponseTime = mDnsPinger.pingDns(mDnsPinger.getDns(),
-                        DNS_PING_TIMEOUT_MS);
-
-                mStatus.dnsCheckTries++;
-                if (pingResponseTime >= 0)
-                    mStatus.dnsCheckSuccesses++;
-
-                if (DBG) {
-                    if (pingResponseTime >= 0) {
-                        mDNSCheckLogStr += " | " + pingResponseTime;
-                    } else {
-                        mDNSCheckLogStr += " | " + "x";
-                    }
-                }
-
-                switch (currentDnsCheckStatus()) {
-                    case SUCCESS:
-                        if (DBG) {
-                            Slog.d(WWS_TAG, mDNSCheckLogStr + " -- Success");
-                        }
-                        doWalledGardenCheck();
-                        break;
-                    case FAILURE:
-                        if (DBG) {
-                            Slog.d(WWS_TAG, mDNSCheckLogStr + " -- Failure");
-                        }
-                        mStatus.state = WatchdogState.DNS_CHECK_FAILURE;
-                        break;
-                    case INCOMPLETE:
-                        // Taking no action
-                        break;
-                }
-                break;
-            case DNS_CHECK_FAILURE:
-                WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
-                if (!mStatus.ssid.equals(wifiInfo.getSSID()) ||
-                        !mStatus.bssid.equals(wifiInfo.getBSSID())) {
-                    Slog.i(WWS_TAG, "handleState DNS_CHECK_FAILURE:: network has changed!");
-                    mStatus.state = WatchdogState.INACTIVE;
-                    break;
-                }
-
-                if (mStatus.numFullDNSchecks >= mStatus.allBssids.size() ||
-                        mStatus.numFullDNSchecks >= MAX_CHECKS_PER_SSID) {
-                    disableAP(wifiInfo);
-                } else {
-                    blacklistAP();
-                }
-                break;
-            case WALLED_GARDEN_DETECTED:
-                popUpBrowser();
-                mStatus.state = WatchdogState.CHECKS_COMPLETE;
-                break;
-            case BLACKLISTED_AP:
-                WifiInfo wifiInfo2 = mWifiManager.getConnectionInfo();
-                if (wifiInfo2.getSupplicantState() != SupplicantState.COMPLETED) {
-                    Slog.d(WWS_TAG,
-                            "handleState::BlacklistedAP - offline, but didn't get disconnect!");
-                    mStatus.state = WatchdogState.INACTIVE;
-                    break;
-                }
-                if (mStatus.bssid.equals(wifiInfo2.getBSSID())) {
-                    Slog.d(WWS_TAG, "handleState::BlacklistedAP - connected to same bssid");
-                    if (!handleSingleDnsCheck()) {
-                        disableAP(wifiInfo2);
-                        break;
-                    }
-                }
-
-                Slog.d(WWS_TAG, "handleState::BlacklistedAP - Simiulating a new connection");
-                handleNewConnection();
-                break;
-        }
-    }
-
-    private void doWalledGardenCheck() {
-        if (!isWalledGardenTestEnabled()) {
-            if (VDBG)
-                Slog.v(WWS_TAG, "Skipping walled garden check - disabled");
-            mStatus.state = WatchdogState.CHECKS_COMPLETE;
-            return;
-        }
-        long waitTime = waitTime(MIN_WALLED_GARDEN_INTERVAL,
-                mStatus.lastWalledGardenCheckTime);
-        if (waitTime > 0) {
-            if (VDBG) {
-                Slog.v(WWS_TAG, "Skipping walled garden check - wait " +
-                        waitTime + " ms.");
-            }
-            mStatus.state = WatchdogState.CHECKS_COMPLETE;
-            return;
-        }
-
-        mStatus.lastWalledGardenCheckTime = SystemClock.elapsedRealtime();
-        if (isWalledGardenConnection()) {
-            if (DBG)
-                Slog.d(WWS_TAG,
-                        "Walled garden test complete - walled garden detected");
-            mStatus.state = WatchdogState.WALLED_GARDEN_DETECTED;
-        } else {
-            if (DBG)
-                Slog.d(WWS_TAG, "Walled garden test complete - online");
-            mStatus.state = WatchdogState.CHECKS_COMPLETE;
-        }
-    }
-
-    private boolean handleSingleDnsCheck() {
-        mStatus.lastSingleCheckTime = SystemClock.elapsedRealtime();
-        long responseTime = mDnsPinger.pingDns(mDnsPinger.getDns(),
-                DNS_PING_TIMEOUT_MS);
-        if (DBG) {
-            Slog.d(WWS_TAG, "Ran a single DNS ping. Response time: " + responseTime);
-        }
-        if (responseTime < 0) {
-            return false;
-        }
-        return true;
-
-    }
-
-    /**
-     * @return Delay in MS before next single DNS check can proceed.
-     */
-    private long timeToNextScheduledDNSCheck() {
-        if (mStatus.signal > LOW_SIGNAL_CUTOFF) {
-            return waitTime(MIN_SINGLE_DNS_CHECK_INTERVAL, mStatus.lastSingleCheckTime);
-        } else {
-            return waitTime(MIN_LOW_SIGNAL_CHECK_INTERVAL, mStatus.lastSingleCheckTime);
-        }
-    }
-
-    /**
-     * Helper to return wait time left given a min interval and last run
-     * 
-     * @param interval minimum wait interval
-     * @param lastTime last time action was performed in
-     *            SystemClock.elapsedRealtime()
-     * @return non negative time to wait
-     */
-    private static long waitTime(long interval, long lastTime) {
-        long wait = interval + lastTime - SystemClock.elapsedRealtime();
-        return wait > 0 ? wait : 0;
-    }
-
-    private void popUpBrowser() {
-        Uri uri = Uri.parse("http://www.google.com");
-        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
-        intent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
-                Intent.FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivity(intent);
-    }
-
-    private void disableAP(WifiInfo info) {
-        // TODO : Unban networks if they had low signal ?
-        Slog.i(WWS_TAG, String.format("Disabling current SSID, %s [bssid %s].  " +
-                "numChecks %d, numAPs %d", mStatus.ssid, mStatus.bssid,
-                mStatus.numFullDNSchecks, mStatus.allBssids.size()));
-        mWifiManager.disableNetwork(info.getNetworkId());
-        mStatus.state = WatchdogState.INACTIVE;
-    }
-
-    private void blacklistAP() {
-        Slog.i(WWS_TAG, String.format("Blacklisting current BSSID %s [ssid %s].  " +
-                "numChecks %d, numAPs %d", mStatus.bssid, mStatus.ssid,
-                mStatus.numFullDNSchecks, mStatus.allBssids.size()));
-
-        mWifiManager.addToBlacklist(mStatus.bssid);
-        mWifiManager.reassociate();
-        mStatus.state = WatchdogState.BLACKLISTED_AP;
-    }
-
-    /**
-     * Checks the scan for new BBIDs using current mSsid
-     */
-    private void updateBssids() {
-        String curSsid = mStatus.ssid;
-        HashSet<String> bssids = mStatus.allBssids;
-        List<ScanResult> results = mWifiManager.getScanResults();
-        int oldNumBssids = bssids.size();
-
-        if (results == null) {
-            if (VDBG) {
-                Slog.v(WWS_TAG, "updateBssids: Got null scan results!");
-            }
-            return;
-        }
-
-        for (ScanResult result : results) {
-            if (result != null && curSsid.equals(result.SSID))
-                bssids.add(result.BSSID);
-        }
-
-        // if (VDBG && bssids.size() - oldNumBssids > 0) {
-        // Slog.v(WWS_TAG,
-        // String.format("updateBssids:: Found %d new APs (total %d) on SSID %s",
-        // bssids.size() - oldNumBssids, bssids.size(), curSsid));
-        // }
-    }
-
-    enum DnsCheckStatus {
-        SUCCESS,
-        FAILURE,
-        INCOMPLETE
-    }
-
-    /**
-     * Computes the current results of the dns check, ends early if outcome is
-     * assured.
-     */
-    private DnsCheckStatus currentDnsCheckStatus() {
-        /**
-         * After a full ping count, if we have more responses than this cutoff,
-         * the outcome is success; else it is 'failure'.
-         */
-        double pingResponseCutoff = MIN_RESPONSE_RATE * NUM_DNS_PINGS;
-        int remainingChecks = NUM_DNS_PINGS - mStatus.dnsCheckTries;
-
-        /**
-         * Our final success count will be at least this big, so we're
-         * guaranteed to succeed.
-         */
-        if (mStatus.dnsCheckSuccesses >= pingResponseCutoff) {
-            return DnsCheckStatus.SUCCESS;
-        }
-
-        /**
-         * Our final count will be at most the current count plus the remaining
-         * pings - we're guaranteed to fail.
-         */
-        if (remainingChecks + mStatus.dnsCheckSuccesses < pingResponseCutoff) {
-            return DnsCheckStatus.FAILURE;
-        }
-
-        return DnsCheckStatus.INCOMPLETE;
-    }
-
-    private void initDnsFullCheck() {
-        if (DBG) {
-            Slog.d(WWS_TAG, "Starting DNS pings at " + SystemClock.elapsedRealtime());
-        }
-        mStatus.numFullDNSchecks++;
-        mStatus.dnsCheckSuccesses = 0;
-        mStatus.dnsCheckTries = 0;
-        mStatus.state = WatchdogState.DNS_FULL_CHECK;
-
-        if (DBG) {
-            mDNSCheckLogStr = String.format("Dns Check %d.  Pinging %s on ssid [%s]: ",
-                    mStatus.numFullDNSchecks, mDnsPinger.getDns(),
-                    mStatus.ssid);
-        }
-    }
-
-    /**
-     * DNS based detection techniques do not work at all hotspots. The one sure
-     * way to check a walled garden is to see if a URL fetch on a known address
-     * fetches the data we expect
-     */
-    private boolean isWalledGardenConnection() {
-        InputStream in = null;
-        HttpURLConnection urlConnection = null;
-        try {
-            URL url = new URL(getWalledGardenUrl());
-            urlConnection = (HttpURLConnection) url.openConnection();
-            in = new BufferedInputStream(urlConnection.getInputStream());
-            Scanner scanner = new Scanner(in);
-            if (scanner.findInLine(getWalledGardenPattern()) != null) {
-                return false;
-            } else {
-                return true;
-            }
-        } catch (IOException e) {
-            return false;
-        } finally {
-            if (in != null) {
-                try {
-                    in.close();
-                } catch (IOException e) {
-                }
-            }
-            if (urlConnection != null)
-                urlConnection.disconnect();
-        }
-    }
-
-    /**
-     * There is little logic inside this class, instead methods of the form
-     * "handle___" are called in the main {@link WifiWatchdogService}.
-     */
-    private class WifiWatchdogHandler extends Handler {
-        /**
-         * Major network event, object is NetworkInfo
-         */
-        static final int MESSAGE_NETWORK_EVENT = 1;
-        /**
-         * Change in settings, no object
-         */
-        static final int MESSAGE_CONTEXT_EVENT = 2;
-
-        /**
-         * Change in signal strength
-         */
-        static final int RSSI_CHANGE_EVENT = 3;
-        static final int SCAN_RESULTS_AVAILABLE = 4;
-
-        static final int WIFI_STATE_CHANGE = 5;
-
-        /**
-         * Single step of state machine. One DNS check, or one WalledGarden
-         * check, or one external action. We separate out external actions to
-         * increase chance of detecting that a check failure is caused by change
-         * in network status. Messages should have an arg1 which to sync status
-         * messages.
-         */
-        static final int CHECK_SEQUENCE_STEP = 10;
-        static final int SINGLE_DNS_CHECK = 11;
-
-        /**
-         * @param looper
-         */
-        public WifiWatchdogHandler(Looper looper) {
-            super(looper);
-        }
-
-        boolean singleCheckQueued = false;
-        long queuedSingleDnsCheckArrival;
-
-        /**
-         * Sends a singleDnsCheck message with shortest time - guards against
-         * multiple.
-         */
-        private boolean queueSingleDnsCheck() {
-            long delay = timeToNextScheduledDNSCheck();
-            long newArrival = delay + SystemClock.elapsedRealtime();
-            if (singleCheckQueued && queuedSingleDnsCheckArrival <= newArrival)
-                return true;
-            queuedSingleDnsCheckArrival = newArrival;
-            singleCheckQueued = true;
-            removeMessages(SINGLE_DNS_CHECK);
-            return sendMessageDelayed(obtainMessage(SINGLE_DNS_CHECK), delay);
-        }
-
-        boolean checkSequenceQueued = false;
-        long queuedCheckSequenceArrival;
-
-        /**
-         * Sends a state_machine_step message if the delay requested is lower
-         * than the current delay.
-         */
-        private boolean sendCheckSequenceStep(long delay) {
-            long newArrival = delay + SystemClock.elapsedRealtime();
-            if (checkSequenceQueued && queuedCheckSequenceArrival <= newArrival)
-                return true;
-            queuedCheckSequenceArrival = newArrival;
-            checkSequenceQueued = true;
-            removeMessages(CHECK_SEQUENCE_STEP);
-            return sendMessageDelayed(obtainMessage(CHECK_SEQUENCE_STEP), delay);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case CHECK_SEQUENCE_STEP:
-                    checkSequenceQueued = false;
-                    handleStateStep();
-                    if (mStatus.state == WatchdogState.CHECKS_COMPLETE) {
-                        queueSingleDnsCheck();
-                    } else if (mStatus.state == WatchdogState.DNS_FULL_CHECK) {
-                        sendCheckSequenceStep(DNS_PING_INTERVAL);
-                    } else if (mStatus.state == WatchdogState.BLACKLISTED_AP) {
-                        sendCheckSequenceStep(BLACKLIST_FOLLOWUP_INTERVAL);
-                    } else if (mStatus.state != WatchdogState.INACTIVE) {
-                        sendCheckSequenceStep(0);
-                    }
-                    return;
-                case MESSAGE_NETWORK_EVENT:
-                    if (!mBroadcastsEnabled) {
-                        Slog.e(WWS_TAG,
-                                "MessageNetworkEvent - WatchdogService not enabled... returning");
-                        return;
-                    }
-                    NetworkInfo info = (NetworkInfo) msg.obj;
-                    switch (info.getState()) {
-                        case DISCONNECTED:
-                            mStatus.state = WatchdogState.INACTIVE;
-                            return;
-                        case CONNECTED:
-                            handleNewConnection();
-                            sendCheckSequenceStep(0);
-                    }
-                    return;
-                case SINGLE_DNS_CHECK:
-                    singleCheckQueued = false;
-                    if (mStatus.state != WatchdogState.CHECKS_COMPLETE) {
-                        Slog.d(WWS_TAG, "Single check returning, curState: " + mStatus.state);
-                        break;
-                    }
-
-                    if (!handleSingleDnsCheck()) {
-                        initDnsFullCheck();
-                        sendCheckSequenceStep(0);
-                    } else {
-                        queueSingleDnsCheck();
-                    }
-
-                    break;
-                case RSSI_CHANGE_EVENT:
-                    updateRssi();
-                    if (mStatus.state == WatchdogState.CHECKS_COMPLETE)
-                        queueSingleDnsCheck();
-                    break;
-                case SCAN_RESULTS_AVAILABLE:
-                    updateBssids();
-                    break;
-                case WIFI_STATE_CHANGE:
-                    if ((Integer) msg.obj == WifiManager.WIFI_STATE_DISABLING) {
-                        Slog.i(WWS_TAG, "WifiStateDisabling -- Resetting WatchdogState");
-                        mStatus = new Status();
-                    }
-                    break;
-                case MESSAGE_CONTEXT_EVENT:
-                    if (isWatchdogEnabled() && !mBroadcastsEnabled) {
-                        mContext.registerReceiver(mBroadcastReceiver, mIntentFilter);
-                        mBroadcastsEnabled = true;
-                        Slog.i(WWS_TAG, "WifiWatchdogService enabled");
-                    } else if (!isWatchdogEnabled() && mBroadcastsEnabled) {
-                        mContext.unregisterReceiver(mBroadcastReceiver);
-                        removeMessages(SINGLE_DNS_CHECK);
-                        removeMessages(CHECK_SEQUENCE_STEP);
-                        mBroadcastsEnabled = false;
-                        Slog.i(WWS_TAG, "WifiWatchdogService disabled");
-                    }
-                    break;
-            }
-        }
-    }
-
-    public void dump(PrintWriter pw) {
-        pw.print("WatchdogStatus: ");
-        pw.print("State " + mStatus.state);
-        pw.println(", network [" + mStatus.ssid + ", " + mStatus.bssid + "]");
-        pw.print("checkCount " + mStatus.numFullDNSchecks);
-        pw.println(", bssids: " + mStatus.allBssids);
-        pw.print(", hasCheckMessages? " +
-                mHandler.hasMessages(WifiWatchdogHandler.CHECK_SEQUENCE_STEP));
-        pw.println(" hasSingleCheckMessages? " +
-                mHandler.hasMessages(WifiWatchdogHandler.SINGLE_DNS_CHECK));
-        pw.println("DNS check log str: " + mDNSCheckLogStr);
-        pw.println("lastSingleCheck: " + mStatus.lastSingleCheckTime);
-    }
-
-    /**
-     * @see android.provider.Settings.Secure#WIFI_WATCHDOG_WALLED_GARDEN_TEST_ENABLED
-     */
-    private Boolean isWalledGardenTestEnabled() {
-        return Settings.Secure.getInt(mContentResolver,
-                Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_TEST_ENABLED, 1) == 1;
-    }
-
-    /**
-     * @see android.provider.Settings.Secure#WIFI_WATCHDOG_WALLED_GARDEN_URL
-     */
-    private String getWalledGardenUrl() {
-        String url = Settings.Secure.getString(mContentResolver,
-                Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_URL);
-        if (TextUtils.isEmpty(url))
-            return "http://www.google.com/";
-        return url;
-    }
-
-    /**
-     * @see android.provider.Settings.Secure#WIFI_WATCHDOG_WALLED_GARDEN_PATTERN
-     */
-    private String getWalledGardenPattern() {
-        String pattern = Settings.Secure.getString(mContentResolver,
-                Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_PATTERN);
-        if (TextUtils.isEmpty(pattern))
-            return "<title>.*Google.*</title>";
-        return pattern;
-    }
-
-    /**
-     * @see android.provider.Settings.Secure#WIFI_WATCHDOG_ON
-     */
-    private boolean isWatchdogEnabled() {
-        return Settings.Secure.getInt(mContentResolver,
-                Settings.Secure.WIFI_WATCHDOG_ON, 1) == 1;
-    }
-}
diff --git a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
new file mode 100644
index 0000000..0eb73b7
--- /dev/null
+++ b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
@@ -0,0 +1,825 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.net.ConnectivityManager;
+import android.net.DnsPinger;
+import android.net.NetworkInfo;
+import android.net.Uri;
+import android.os.Message;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Slog;
+
+import com.android.internal.util.Protocol;
+import com.android.internal.util.State;
+import com.android.internal.util.StateMachine;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Scanner;
+
+/**
+ * {@link WifiWatchdogStateMachine} monitors the initial connection to a Wi-Fi
+ * network with multiple access points. After the framework successfully
+ * connects to an access point, the watchdog verifies connectivity by 'pinging'
+ * the configured DNS server using {@link DnsPinger}.
+ * <p>
+ * On DNS check failure, the BSSID is blacklisted if it is reasonably likely
+ * that another AP might have internet access; otherwise the SSID is disabled.
+ * <p>
+ * On DNS success, the WatchdogService initiates a walled garden check via an
+ * http get. A browser window is activated if a walled garden is detected.
+ *
+ * @hide
+ */
+public class WifiWatchdogStateMachine extends StateMachine {
+
+    private static final boolean VDBG = false;
+    private static final boolean DBG = true;
+    private static final String WWSM_TAG = "WifiWatchdogStateMachine";
+
+    private static final int WIFI_SIGNAL_LEVELS = 4;
+    /**
+     * Low signal is defined as less than or equal to cut off
+     */
+    private static final int LOW_SIGNAL_CUTOFF = 1;
+
+    private static final long MIN_LOW_SIGNAL_CHECK_INTERVAL_MS = 2 * 60 * 1000;
+    private static final long MIN_SINGLE_DNS_CHECK_INTERVAL_MS = 10 * 60 * 1000;
+    private static final long MIN_WALLED_GARDEN_INTERVAL_MS = 30 * 60 * 1000;
+
+    private static final int MAX_CHECKS_PER_SSID = 7;
+    private static final int NUM_DNS_PINGS = 5;
+    private static final double MIN_DNS_RESPONSE_RATE = 0.50;
+
+    private static final int DNS_PING_TIMEOUT_MS = 800;
+    private static final long DNS_PING_INTERVAL_MS = 100;
+
+    private static final long BLACKLIST_FOLLOWUP_INTERVAL_MS = 15 * 1000;
+
+    private static final int BASE = Protocol.BASE_WIFI_WATCHDOG;
+
+    /**
+     * Indicates the enable setting of WWS may have changed
+     */
+    private static final int EVENT_WATCHDOG_TOGGLED = BASE + 1;
+
+    /**
+     * Indicates the wifi network state has changed. Passed w/ original intent
+     * which has a non-null networkInfo object
+     */
+    private static final int EVENT_NETWORK_STATE_CHANGE = BASE + 2;
+    /**
+     * Indicates the signal has changed. Passed with arg1
+     * {@link #mNetEventCounter} and arg2 [raw signal strength]
+     */
+    private static final int EVENT_RSSI_CHANGE = BASE + 3;
+    private static final int EVENT_SCAN_RESULTS_AVAILABLE = BASE + 4;
+    private static final int EVENT_WIFI_RADIO_STATE_CHANGE = BASE + 5;
+
+    private static final int MESSAGE_CHECK_STEP = BASE + 100;
+    private static final int MESSAGE_HANDLE_WALLED_GARDEN = BASE + 101;
+    private static final int MESSAGE_HANDLE_BAD_AP = BASE + 102;
+    /**
+     * arg1 == mOnlineWatchState.checkCount
+     */
+    private static final int MESSAGE_SINGLE_DNS_CHECK = BASE + 103;
+    private static final int MESSAGE_NETWORK_FOLLOWUP = BASE + 104;
+
+    private Context mContext;
+    private ContentResolver mContentResolver;
+    private WifiManager mWifiManager;
+    private DnsPinger mDnsPinger;
+    private IntentFilter mIntentFilter;
+    private BroadcastReceiver mBroadcastReceiver;
+
+    private DefaultState mDefaultState = new DefaultState();
+    private WatchdogDisabledState mWatchdogDisabledState = new WatchdogDisabledState();
+    private WatchdogEnabledState mWatchdogEnabledState = new WatchdogEnabledState();
+    private NotConnectedState mNotConnectedState = new NotConnectedState();
+    private ConnectedState mConnectedState = new ConnectedState();
+    private DnsCheckingState mDnsCheckingState = new DnsCheckingState();
+    private OnlineWatchState mOnlineWatchState = new OnlineWatchState();
+    private DnsCheckFailureState mDnsCheckFailureState = new DnsCheckFailureState();
+    private WalledGardenState mWalledGardenState = new WalledGardenState();
+    private BlacklistedApState mBlacklistedApState = new BlacklistedApState();
+
+    /**
+     * The {@link WifiInfo} object passed to WWSM on network broadcasts
+     */
+    private WifiInfo mInitialConnInfo;
+    private int mNetEventCounter = 0;
+
+    /**
+     * Currently maintained but not used, TODO
+     */
+    private HashSet<String> mBssids = new HashSet<String>();
+    private int mNumFullDNSchecks = 0;
+
+    private Long mLastWalledGardenCheckTime = null;
+
+    /**
+     * This is set by the blacklisted state and reset when connected to a new AP.
+     * It triggers a disableNetwork call if a DNS check fails.
+     */
+    public boolean mDisableAPNextFailure = false;
+
+    /**
+     * STATE MAP
+     *          Default
+     *         /       \
+     * Disabled     Enabled
+     *             /       \
+     * Disconnected      Connected
+     *                  /---------\
+     *               (all other states)
+     */
+    private WifiWatchdogStateMachine(Context context) {
+        super(WWSM_TAG);
+        mContext = context;
+        mContentResolver = context.getContentResolver();
+        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+        mDnsPinger = new DnsPinger("WifiWatchdogServer.DnsPinger", context,
+                ConnectivityManager.TYPE_WIFI);
+
+        setupNetworkReceiver();
+
+        // The content observer to listen needs a handler
+        registerForSettingsChanges();
+        addState(mDefaultState);
+            addState(mWatchdogDisabledState, mDefaultState);
+            addState(mWatchdogEnabledState, mDefaultState);
+                addState(mNotConnectedState, mWatchdogEnabledState);
+                addState(mConnectedState, mWatchdogEnabledState);
+                    addState(mDnsCheckingState, mConnectedState);
+                    addState(mDnsCheckFailureState, mConnectedState);
+                    addState(mWalledGardenState, mConnectedState);
+                    addState(mBlacklistedApState, mConnectedState);
+                    addState(mOnlineWatchState, mConnectedState);
+
+        setInitialState(mWatchdogDisabledState);
+    }
+
+    public static WifiWatchdogStateMachine makeWifiWatchdogStateMachine(Context context) {
+        WifiWatchdogStateMachine wwsm = new WifiWatchdogStateMachine(context);
+        wwsm.start();
+        wwsm.sendMessage(EVENT_WATCHDOG_TOGGLED);
+        return wwsm;
+    }
+
+    /**
+   *
+   */
+    private void setupNetworkReceiver() {
+        mBroadcastReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                String action = intent.getAction();
+                if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
+                    sendMessage(EVENT_NETWORK_STATE_CHANGE, intent);
+                } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
+                    obtainMessage(EVENT_RSSI_CHANGE, mNetEventCounter,
+                            intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200)).sendToTarget();
+                } else if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
+                    sendMessage(EVENT_SCAN_RESULTS_AVAILABLE);
+                } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
+                    sendMessage(EVENT_WIFI_RADIO_STATE_CHANGE,
+                            intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
+                                    WifiManager.WIFI_STATE_UNKNOWN));
+                }
+            }
+        };
+
+        mIntentFilter = new IntentFilter();
+        mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+        mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
+        mIntentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);
+        mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
+    }
+
+    /**
+     * Observes the watchdog on/off setting, and takes action when changed.
+     */
+    private void registerForSettingsChanges() {
+        ContentObserver contentObserver = new ContentObserver(this.getHandler()) {
+            @Override
+            public void onChange(boolean selfChange) {
+                sendMessage(EVENT_WATCHDOG_TOGGLED);
+            }
+        };
+
+        mContext.getContentResolver().registerContentObserver(
+                Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_ON),
+                false, contentObserver);
+    }
+
+    /**
+     * DNS based detection techniques do not work at all hotspots. The one sure
+     * way to check a walled garden is to see if a URL fetch on a known address
+     * fetches the data we expect
+     */
+    private boolean isWalledGardenConnection() {
+        InputStream in = null;
+        HttpURLConnection urlConnection = null;
+        try {
+            URL url = new URL(getWalledGardenUrl());
+            urlConnection = (HttpURLConnection) url.openConnection();
+            in = new BufferedInputStream(urlConnection.getInputStream());
+            Scanner scanner = new Scanner(in);
+            if (scanner.findInLine(getWalledGardenPattern()) != null) {
+                return false;
+            } else {
+                return true;
+            }
+        } catch (IOException e) {
+            return false;
+        } finally {
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (IOException e) {
+                }
+            }
+            if (urlConnection != null)
+                urlConnection.disconnect();
+        }
+    }
+
+    private boolean rssiStrengthAboveCutoff(int rssi) {
+        return WifiManager.calculateSignalLevel(rssi, WIFI_SIGNAL_LEVELS) > LOW_SIGNAL_CUTOFF;
+    }
+
+    public void dump(PrintWriter pw) {
+        pw.print("WatchdogStatus: ");
+        pw.print("State " + getCurrentState());
+        pw.println(", network [" + mInitialConnInfo + "]");
+        pw.print("checkCount " + mNumFullDNSchecks);
+        pw.println(", bssids: " + mBssids);
+        pw.println("lastSingleCheck: " + mOnlineWatchState.lastCheckTime);
+    }
+
+    /**
+     * @see android.provider.Settings.Secure#WIFI_WATCHDOG_WALLED_GARDEN_TEST_ENABLED
+     */
+    private Boolean isWalledGardenTestEnabled() {
+        return Settings.Secure.getInt(mContentResolver,
+                Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_TEST_ENABLED, 1) == 1;
+    }
+
+    /**
+     * @see android.provider.Settings.Secure#WIFI_WATCHDOG_WALLED_GARDEN_URL
+     */
+    private String getWalledGardenUrl() {
+        String url = Settings.Secure.getString(mContentResolver,
+                Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_URL);
+        if (TextUtils.isEmpty(url))
+            return "http://www.google.com/";
+        return url;
+    }
+
+    /**
+     * @see android.provider.Settings.Secure#WIFI_WATCHDOG_WALLED_GARDEN_PATTERN
+     */
+    private String getWalledGardenPattern() {
+        String pattern = Settings.Secure.getString(mContentResolver,
+                Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_PATTERN);
+        if (TextUtils.isEmpty(pattern))
+            return "<title>.*Google.*</title>";
+        return pattern;
+    }
+
+    /**
+     * @see android.provider.Settings.Secure#WIFI_WATCHDOG_ON
+     */
+    private boolean isWatchdogEnabled() {
+        return Settings.Secure.getInt(mContentResolver,
+                Settings.Secure.WIFI_WATCHDOG_ON, 1) == 1;
+    }
+
+
+    /**
+     * Helper to return wait time left given a min interval and last run
+     *
+     * @param interval minimum wait interval
+     * @param lastTime last time action was performed in
+     *            SystemClock.elapsedRealtime(). Null if never.
+     * @return non negative time to wait
+     */
+    private static long waitTime(long interval, Long lastTime) {
+        if (lastTime == null)
+            return 0;
+        long wait = interval + lastTime - SystemClock.elapsedRealtime();
+        return wait > 0 ? wait : 0;
+    }
+
+    private static String wifiInfoToStr(WifiInfo wifiInfo) {
+        if (wifiInfo == null)
+            return "null";
+        return "(" + wifiInfo.getSSID() + ", " + wifiInfo.getBSSID() + ")";
+    }
+
+    /**
+   *
+   */
+    private void resetWatchdogState() {
+        mInitialConnInfo = null;
+        mDisableAPNextFailure = false;
+        mLastWalledGardenCheckTime = null;
+        mNumFullDNSchecks = 0;
+        mBssids.clear();
+    }
+
+    private void popUpBrowser() {
+        Uri uri = Uri.parse("http://www.google.com");
+        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+        intent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
+                Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(intent);
+    }
+
+    private void sendCheckStepMessage(long delay) {
+        sendMessageDelayed(obtainMessage(MESSAGE_CHECK_STEP, mNetEventCounter, 0), delay);
+    }
+
+    class DefaultState extends State {
+        @Override
+        public boolean processMessage(Message msg) {
+            if (VDBG) {
+                Slog.v(WWSM_TAG, "Caught message " + msg.what + " in state " +
+                        getCurrentState().getName());
+            }
+            return HANDLED;
+        }
+    }
+
+    class WatchdogDisabledState extends State {
+        @Override
+        public boolean processMessage(Message msg) {
+            switch (msg.what) {
+                case EVENT_WATCHDOG_TOGGLED:
+                    if (isWatchdogEnabled())
+                        transitionTo(mNotConnectedState);
+                    return HANDLED;
+            }
+            return NOT_HANDLED;
+        }
+    }
+
+    class WatchdogEnabledState extends State {
+        @Override
+        public void enter() {
+            resetWatchdogState();
+            mContext.registerReceiver(mBroadcastReceiver, mIntentFilter);
+            Slog.i(WWSM_TAG, "WifiWatchdogService enabled");
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            switch (msg.what) {
+                case EVENT_WATCHDOG_TOGGLED:
+                    if (!isWatchdogEnabled())
+                        transitionTo(mWatchdogDisabledState);
+                    return HANDLED;
+                case EVENT_NETWORK_STATE_CHANGE:
+                    Intent stateChangeIntent = (Intent) msg.obj;
+                    NetworkInfo networkInfo = (NetworkInfo)
+                            stateChangeIntent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
+
+                    switch (networkInfo.getState()) {
+                        case CONNECTED:
+                            // WifiInfo wifiInfo = (WifiInfo)
+                            //         stateChangeIntent
+                            //                 .getParcelableExtra(WifiManager.EXTRA_WIFI_INFO);
+                            // TODO : Replace with above code when API is changed
+                            WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
+                            if (wifiInfo == null) {
+                                Slog.e(WWSM_TAG, "Connected --> WifiInfo object null!");
+                                return HANDLED;
+                            }
+
+                            if (wifiInfo.getSSID() == null || wifiInfo.getBSSID() == null) {
+                                Slog.e(WWSM_TAG, "Received wifiInfo object with null elts: "
+                                        + wifiInfoToStr(wifiInfo));
+                                return HANDLED;
+                            }
+
+                            initConnection(wifiInfo);
+                            transitionTo(mDnsCheckingState);
+                            mNetEventCounter++;
+                            return HANDLED;
+                        case DISCONNECTED:
+                        case DISCONNECTING:
+                            mNetEventCounter++;
+                            transitionTo(mNotConnectedState);
+                            return HANDLED;
+                    }
+                    return HANDLED;
+                case EVENT_WIFI_RADIO_STATE_CHANGE:
+                    if ((Integer) msg.obj == WifiManager.WIFI_STATE_DISABLING) {
+                        Slog.i(WWSM_TAG, "WifiStateDisabling -- Resetting WatchdogState");
+                        resetWatchdogState();
+                        mNetEventCounter++;
+                        transitionTo(mNotConnectedState);
+                    }
+                    return HANDLED;
+            }
+
+            return NOT_HANDLED;
+        }
+
+        /**
+         * @param wifiInfo Info object with non-null ssid and bssid
+         */
+        private void initConnection(WifiInfo wifiInfo) {
+            if (VDBG) {
+                Slog.v(WWSM_TAG, "Connected:: old " + wifiInfoToStr(mInitialConnInfo) +
+                        " ==> new " + wifiInfoToStr(wifiInfo));
+            }
+
+            if (mInitialConnInfo == null || !wifiInfo.getSSID().equals(mInitialConnInfo.getSSID())) {
+                resetWatchdogState();
+            } else if (!wifiInfo.getBSSID().equals(mInitialConnInfo.getBSSID())) {
+                mDisableAPNextFailure = false;
+            }
+            mInitialConnInfo = wifiInfo;
+        }
+
+        @Override
+        public void exit() {
+            mContext.unregisterReceiver(mBroadcastReceiver);
+            Slog.i(WWSM_TAG, "WifiWatchdogService disabled");
+        }
+    }
+
+    class NotConnectedState extends State {
+    }
+
+    class ConnectedState extends State {
+        @Override
+        public boolean processMessage(Message msg) {
+            switch (msg.what) {
+                case EVENT_SCAN_RESULTS_AVAILABLE:
+                    String curSsid = mInitialConnInfo.getSSID();
+                    List<ScanResult> results = mWifiManager.getScanResults();
+                    int oldNumBssids = mBssids.size();
+
+                    if (results == null) {
+                        if (DBG) {
+                            Slog.d(WWSM_TAG, "updateBssids: Got null scan results!");
+                        }
+                        return HANDLED;
+                    }
+
+                    for (ScanResult result : results) {
+                        if (result == null || result.SSID == null) {
+                            if (VDBG) {
+                                Slog.v(WWSM_TAG, "Received invalid scan result: " + result);
+                            }
+                            continue;
+                        }
+                        if (curSsid.equals(result.SSID))
+                            mBssids.add(result.BSSID);
+                    }
+                    return HANDLED;
+            }
+            return NOT_HANDLED;
+        }
+
+    }
+
+    class DnsCheckingState extends State {
+        int dnsCheckTries = 0;
+        int dnsCheckSuccesses = 0;
+        String dnsCheckLogStr = "";
+
+        @Override
+        public void enter() {
+            mNumFullDNSchecks++;
+            dnsCheckSuccesses = 0;
+            dnsCheckTries = 0;
+            if (DBG) {
+                Slog.d(WWSM_TAG, "Starting DNS pings at " + SystemClock.elapsedRealtime());
+                dnsCheckLogStr = String.format("Dns Check %d.  Pinging %s on ssid [%s]: ",
+                        mNumFullDNSchecks, mDnsPinger.getDns(), mInitialConnInfo.getSSID());
+            }
+
+            sendCheckStepMessage(0);
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            if (msg.what != MESSAGE_CHECK_STEP) {
+                return NOT_HANDLED;
+            }
+            if (msg.arg1 != mNetEventCounter) {
+                Slog.d(WWSM_TAG, "Check step out of sync, ignoring...");
+                return HANDLED;
+            }
+
+            long pingResponseTime = mDnsPinger.pingDns(mDnsPinger.getDns(),
+                    DNS_PING_TIMEOUT_MS);
+
+            dnsCheckTries++;
+            if (pingResponseTime >= 0)
+                dnsCheckSuccesses++;
+
+            if (DBG) {
+                if (pingResponseTime >= 0) {
+                    dnsCheckLogStr += "|" + pingResponseTime;
+                } else {
+                    dnsCheckLogStr += "|x";
+                }
+            }
+
+            if (VDBG) {
+                Slog.v(WWSM_TAG, dnsCheckLogStr);
+            }
+
+            /**
+             * After a full ping count, if we have more responses than this
+             * cutoff, the outcome is success; else it is 'failure'.
+             */
+            double pingResponseCutoff = MIN_DNS_RESPONSE_RATE * NUM_DNS_PINGS;
+            int remainingChecks = NUM_DNS_PINGS - dnsCheckTries;
+
+            /**
+             * Our final success count will be at least this big, so we're
+             * guaranteed to succeed.
+             */
+            if (dnsCheckSuccesses >= pingResponseCutoff) {
+                // DNS CHECKS OK, NOW WALLED GARDEN
+                if (DBG) {
+                    Slog.d(WWSM_TAG, dnsCheckLogStr + "|  SUCCESS");
+                }
+
+                if (!shouldCheckWalledGarden()) {
+                    transitionTo(mOnlineWatchState);
+                    return HANDLED;
+                }
+
+                mLastWalledGardenCheckTime = SystemClock.elapsedRealtime();
+                if (isWalledGardenConnection()) {
+                    if (DBG)
+                        Slog.d(WWSM_TAG,
+                                "Walled garden test complete - walled garden detected");
+                    transitionTo(mWalledGardenState);
+                } else {
+                    if (DBG)
+                        Slog.d(WWSM_TAG, "Walled garden test complete - online");
+                    transitionTo(mOnlineWatchState);
+                }
+                return HANDLED;
+            }
+
+            /**
+             * Our final count will be at most the current count plus the
+             * remaining pings - we're guaranteed to fail.
+             */
+            if (remainingChecks + dnsCheckSuccesses < pingResponseCutoff) {
+                if (DBG) {
+                    Slog.d(WWSM_TAG, dnsCheckLogStr + "|  FAILURE");
+                }
+                transitionTo(mDnsCheckFailureState);
+                return HANDLED;
+            }
+
+            // Still in dns check step
+            sendCheckStepMessage(DNS_PING_INTERVAL_MS);
+            return HANDLED;
+        }
+
+        private boolean shouldCheckWalledGarden() {
+            if (!isWalledGardenTestEnabled()) {
+                if (VDBG)
+                    Slog.v(WWSM_TAG, "Skipping walled garden check - disabled");
+                return false;
+            }
+            long waitTime = waitTime(MIN_WALLED_GARDEN_INTERVAL_MS,
+                    mLastWalledGardenCheckTime);
+            if (waitTime > 0) {
+                if (DBG) {
+                    Slog.d(WWSM_TAG, "Skipping walled garden check - wait " +
+                            waitTime + " ms.");
+                }
+                return false;
+            }
+            return true;
+        }
+
+    }
+
+    class OnlineWatchState extends State {
+        /**
+         * Signals a short-wait message is enqueued for the current 'guard' counter
+         */
+        boolean unstableSignalChecks = false;
+
+        /**
+         * The signal is unstable.  We should enqueue a short-wait check, if one is enqueued
+         * already
+         */
+        boolean signalUnstable = false;
+
+        /**
+         * A monotonic counter to ensure that at most one check message will be processed from any
+         * set of check messages currently enqueued.  Avoids duplicate checks when a low-signal
+         * event is observed.
+         */
+        int checkGuard = 0;
+        Long lastCheckTime = null;
+
+        @Override
+        public void enter() {
+            lastCheckTime = SystemClock.elapsedRealtime();
+            signalUnstable = false;
+            checkGuard++;
+            unstableSignalChecks = false;
+            triggerSingleDnsCheck();
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            switch (msg.what) {
+                case EVENT_RSSI_CHANGE:
+                    if (msg.arg1 != mNetEventCounter) {
+                        if (DBG) {
+                            Slog.d(WWSM_TAG, "Rssi change message out of sync, ignoring");
+                        }
+                        return HANDLED;
+                    }
+                    int newRssi = msg.arg2;
+                    signalUnstable = !rssiStrengthAboveCutoff(newRssi);
+                    if (VDBG) {
+                        Slog.v(WWSM_TAG, "OnlineWatchState:: new rssi " + newRssi + " --> level " +
+                                WifiManager.calculateSignalLevel(newRssi, WIFI_SIGNAL_LEVELS));
+                    }
+
+                    if (signalUnstable && !unstableSignalChecks) {
+                        if (VDBG) {
+                            Slog.v(WWSM_TAG, "Sending triggered check msg");
+                        }
+                        triggerSingleDnsCheck();
+                    }
+                    return HANDLED;
+                case MESSAGE_SINGLE_DNS_CHECK:
+                    if (msg.arg1 != checkGuard) {
+                        if (VDBG) {
+                            Slog.v(WWSM_TAG, "Single check msg out of sync, ignoring.");
+                        }
+                        return HANDLED;
+                    }
+                    lastCheckTime = SystemClock.elapsedRealtime();
+                    long responseTime = mDnsPinger.pingDns(mDnsPinger.getDns(),
+                            DNS_PING_TIMEOUT_MS);
+                    if (responseTime >= 0) {
+                        if (VDBG) {
+                            Slog.v(WWSM_TAG, "Ran a single DNS ping. Response time: "
+                                    + responseTime);
+                        }
+
+                        checkGuard++;
+                        unstableSignalChecks = false;
+                        triggerSingleDnsCheck();
+                    } else {
+                        if (DBG) {
+                            Slog.d(WWSM_TAG, "Single dns ping failure. Starting full checks.");
+                        }
+                        transitionTo(mDnsCheckingState);
+                    }
+                    return HANDLED;
+            }
+            return NOT_HANDLED;
+        }
+
+        /**
+         * Times a dns check with an interval based on {@link #curSignalStable}
+         */
+        private void triggerSingleDnsCheck() {
+            long waitInterval;
+            if (signalUnstable) {
+                waitInterval = MIN_LOW_SIGNAL_CHECK_INTERVAL_MS;
+                unstableSignalChecks = true;
+            } else {
+                waitInterval = MIN_SINGLE_DNS_CHECK_INTERVAL_MS;
+            }
+            sendMessageDelayed(obtainMessage(MESSAGE_SINGLE_DNS_CHECK, checkGuard, 0),
+                    waitTime(waitInterval, lastCheckTime));
+        }
+    }
+
+    class DnsCheckFailureState extends State {
+        @Override
+        public void enter() {
+            obtainMessage(MESSAGE_HANDLE_BAD_AP, mNetEventCounter, 0).sendToTarget();
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            if (msg.what != MESSAGE_HANDLE_BAD_AP) {
+                return NOT_HANDLED;
+            }
+
+            if (msg.arg1 != mNetEventCounter) {
+                if (VDBG) {
+                    Slog.v(WWSM_TAG, "Msg out of sync, ignoring...");
+                }
+                return HANDLED;
+            }
+
+            if (mDisableAPNextFailure || mNumFullDNSchecks >= MAX_CHECKS_PER_SSID) {
+                // TODO : Unban networks if they had low signal ?
+                Slog.i(WWSM_TAG, "Disabling current SSID " + wifiInfoToStr(mInitialConnInfo)
+                        + ".  " +
+                        "numChecks " + mNumFullDNSchecks + ", numAPs " + mBssids.size());
+                mWifiManager.disableNetwork(mInitialConnInfo.getNetworkId());
+                transitionTo(mNotConnectedState);
+            } else {
+                Slog.i(WWSM_TAG, "Blacklisting current BSSID.  " + wifiInfoToStr(mInitialConnInfo) +
+                        "numChecks " + mNumFullDNSchecks + ", numAPs " + mBssids.size());
+
+                mWifiManager.addToBlacklist(mInitialConnInfo.getBSSID());
+                mWifiManager.reassociate();
+                transitionTo(mBlacklistedApState);
+            }
+            return HANDLED;
+        }
+    }
+
+    class WalledGardenState extends State {
+        @Override
+        public void enter() {
+            obtainMessage(MESSAGE_HANDLE_WALLED_GARDEN, mNetEventCounter, 0).sendToTarget();
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            if (msg.what != MESSAGE_HANDLE_WALLED_GARDEN) {
+                return NOT_HANDLED;
+            }
+
+            if (msg.arg1 != mNetEventCounter) {
+                if (VDBG) {
+                    Slog.v(WWSM_TAG, "WalledGardenState::Msg out of sync, ignoring...");
+                }
+                return HANDLED;
+            }
+            popUpBrowser();
+            transitionTo(mOnlineWatchState);
+            return HANDLED;
+        }
+    }
+
+    class BlacklistedApState extends State {
+        @Override
+        public void enter() {
+            mDisableAPNextFailure = true;
+            sendMessageDelayed(obtainMessage(MESSAGE_NETWORK_FOLLOWUP, mNetEventCounter, 0),
+                    BLACKLIST_FOLLOWUP_INTERVAL_MS);
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            if (msg.what != MESSAGE_NETWORK_FOLLOWUP) {
+                return NOT_HANDLED;
+            }
+
+            if (msg.arg1 != mNetEventCounter) {
+                if (VDBG) {
+                    Slog.v(WWSM_TAG, "BlacklistedApState::Msg out of sync, ignoring...");
+                }
+                return HANDLED;
+            }
+
+            transitionTo(mDnsCheckingState);
+            return HANDLED;
+        }
+    }
+}
