/*
 * 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 com.android.server;

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.NetworkInfo;
import android.net.DhcpInfo;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiStateTracker;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Config;
import android.util.Log;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.List;
import java.util.Random;

/**
 * {@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 whether the DNS server is
 * reachable. If not, the watchdog blacklists the current access point, leading
 * to a connection on another access point within the same network.
 * <p>
 * The watchdog has a few safeguards:
 * <ul>
 * <li>Only monitor networks with multiple access points
 * <li>Only check at most {@link #getMaxApChecks()} different access points
 * within the network before giving up
 * <p>
 * The watchdog checks for connectivity on an access point by ICMP pinging the
 * DNS. There are settings that allow disabling the watchdog, or tweaking the
 * acceptable packet loss (and other various parameters).
 * <p>
 * The core logic of the watchdog is done on the main watchdog thread. Wi-Fi
 * callbacks can come in on other threads, so we must queue messages to the main
 * watchdog thread's handler. Most (if not all) state is only written to from
 * the main thread.
 * 
 * {@hide}
 */
public class WifiWatchdogService {
    private static final String TAG = "WifiWatchdogService";
    private static final boolean V = false || Config.LOGV;
    private static final boolean D = true || Config.LOGD;
    
    /*
     * When this was "net.dns1", sometimes the mobile data's DNS was seen
     * instead due to a race condition. All we really care about is the
     * DHCP-replied DNS server anyway.
     */
    /** The system property whose value provides the current DNS address. */
    private static final String SYSTEMPROPERTY_KEY_DNS = "dhcp.tiwlan0.dns1";

    private Context mContext;
    private ContentResolver mContentResolver;
    private WifiStateTracker mWifiStateTracker;
    private WifiManager mWifiManager;
    
    /**
     * The main watchdog thread.
     */
    private WifiWatchdogThread mThread;
    /**
     * The handler for the main watchdog thread.
     */
    private WifiWatchdogHandler mHandler;

    /**
     * The current watchdog state. Only written from the main thread!
     */
    private WatchdogState mState = WatchdogState.IDLE;
    /**
     * The SSID of the network that the watchdog is currently monitoring. Only
     * touched in the main thread!
     */
    private String mSsid;
    /**
     * The number of access points in the current network ({@link #mSsid}) that
     * have been checked. Only touched in the main thread!
     */
    private int mNumApsChecked;
    /** Whether the current AP check should be canceled. */
    private boolean mShouldCancel;
    
    WifiWatchdogService(Context context, WifiStateTracker wifiStateTracker) {
        mContext = context;
        mContentResolver = context.getContentResolver();
        mWifiStateTracker = wifiStateTracker;
        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        
        createThread();
        
        // The content observer to listen needs a handler, which createThread creates
        registerForSettingsChanges();
        if (isWatchdogEnabled()) {
            registerForWifiBroadcasts();
        }
        
        if (V) {
            myLogV("WifiWatchdogService: Created");
        }
    }

    /**
     * Observes the watchdog on/off setting, and takes action when changed.
     */
    private void registerForSettingsChanges() {
        ContentResolver contentResolver = mContext.getContentResolver();
        contentResolver.registerContentObserver(
                Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_ON), false,
                new ContentObserver(mHandler) {
            @Override
            public void onChange(boolean selfChange) {
                if (isWatchdogEnabled()) {
                    registerForWifiBroadcasts();
                } else {
                    unregisterForWifiBroadcasts();
                    if (mHandler != null) {
                        mHandler.disableWatchdog();
                    }
                }
            }
        });
    }

    /**
     * @see android.provider.Settings.Secure#WIFI_WATCHDOG_ON
     */
    private boolean isWatchdogEnabled() {
        return Settings.Secure.getInt(mContentResolver, Settings.Secure.WIFI_WATCHDOG_ON, 1) == 1;
    }
    
    /**
     * @see android.provider.Settings.Secure#WIFI_WATCHDOG_AP_COUNT
     */
    private int getApCount() {
        return Settings.Secure.getInt(mContentResolver,
            Settings.Secure.WIFI_WATCHDOG_AP_COUNT, 2);
    }
    
    /**
     * @see android.provider.Settings.Secure#WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT
     */
    private int getInitialIgnoredPingCount() {
        return Settings.Secure.getInt(mContentResolver,
            Settings.Secure.WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT , 2);
    }

    /**
     * @see android.provider.Settings.Secure#WIFI_WATCHDOG_PING_COUNT
     */
    private int getPingCount() {
        return Settings.Secure.getInt(mContentResolver,
            Settings.Secure.WIFI_WATCHDOG_PING_COUNT, 4);
    }
    
    /**
     * @see android.provider.Settings.Secure#WIFI_WATCHDOG_PING_TIMEOUT_MS
     */
    private int getPingTimeoutMs() {
        return Settings.Secure.getInt(mContentResolver,
            Settings.Secure.WIFI_WATCHDOG_PING_TIMEOUT_MS, 500);
    }
    
    /**
     * @see android.provider.Settings.Secure#WIFI_WATCHDOG_PING_DELAY_MS
     */
    private int getPingDelayMs() {
        return Settings.Secure.getInt(mContentResolver,
            Settings.Secure.WIFI_WATCHDOG_PING_DELAY_MS, 250);
    }
    
    /**
     * @see android.provider.Settings.Secure#WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE
     */
    private int getAcceptablePacketLossPercentage() {
        return Settings.Secure.getInt(mContentResolver,
            Settings.Secure.WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE, 25);
    }
    
    /**
     * @see android.provider.Settings.Secure#WIFI_WATCHDOG_MAX_AP_CHECKS
     */
    private int getMaxApChecks() {
        return Settings.Secure.getInt(mContentResolver,
            Settings.Secure.WIFI_WATCHDOG_MAX_AP_CHECKS, 7);
    }
    
    /**
     * @see android.provider.Settings.Secure#WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED
     */
    private boolean isBackgroundCheckEnabled() {
        return Settings.Secure.getInt(mContentResolver,
            Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED, 1) == 1;
    }
    
    /**
     * @see android.provider.Settings.Secure#WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS
     */
    private int getBackgroundCheckDelayMs() {
        return Settings.Secure.getInt(mContentResolver,
            Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS, 60000);
    }
    
    /**
     * @see android.provider.Settings.Secure#WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS
     */
    private int getBackgroundCheckTimeoutMs() {
        return Settings.Secure.getInt(mContentResolver,
            Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS, 1000);
    }

    /**
     * @see android.provider.Settings.Secure#WIFI_WATCHDOG_WATCH_LIST
     * @return the comma-separated list of SSIDs
     */
    private String getWatchList() {
        return Settings.Secure.getString(mContentResolver,
                Settings.Secure.WIFI_WATCHDOG_WATCH_LIST);
    }
    
    /**
     * Registers to receive the necessary Wi-Fi broadcasts.
     */
    private void registerForWifiBroadcasts() {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        intentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
        intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
        mContext.registerReceiver(mReceiver, intentFilter);
    }

    /**
     * Unregisters from receiving the Wi-Fi broadcasts.
     */
    private void unregisterForWifiBroadcasts() {
        mContext.unregisterReceiver(mReceiver);
    }

    /**
     * Creates the main watchdog thread, including waiting for the handler to be
     * created.
     */
    private void createThread() {
        mThread = new WifiWatchdogThread();
        mThread.start();
        waitForHandlerCreation();
    }

    /**
     * Waits for the main watchdog thread to create the handler.
     */
    private void waitForHandlerCreation() {
        synchronized(this) {
            while (mHandler == null) {
                try {
                    // Wait for the handler to be set by the other thread
                    wait();
                } catch (InterruptedException e) {
                    Log.e(TAG, "Interrupted while waiting on handler.");
                }
            }
        }
    }

    // Utility methods
    
    /**
     * Logs with the current thread.
     */
    private static void myLogV(String message) {
        Log.v(TAG, "(" + Thread.currentThread().getName() + ") " + message);
    }
    
    private static void myLogD(String message) {
        Log.d(TAG, "(" + Thread.currentThread().getName() + ") " + message);
    }
    
    /**
     * Gets the DNS of the current AP.
     * 
     * @return The DNS of the current AP.
     */
    private int getDns() {
        DhcpInfo addressInfo = mWifiManager.getDhcpInfo();
        if (addressInfo != null) {
            return addressInfo.dns1;
        } else {
            return -1;
        }
    }
    
    /**
     * Checks whether the DNS can be reached using multiple attempts according
     * to the current setting values.
     * 
     * @return Whether the DNS is reachable
     */
    private boolean checkDnsConnectivity() {
        int dns = getDns();
        if (dns == -1) {
            if (V) {
                myLogV("checkDnsConnectivity: Invalid DNS, returning false");
            }
            return false;
        }
        
        if (V) {
            myLogV("checkDnsConnectivity: Checking 0x" +
                    Integer.toHexString(Integer.reverseBytes(dns)) + " for connectivity");
        }

        int numInitialIgnoredPings = getInitialIgnoredPingCount();
        int numPings = getPingCount();
        int pingDelay = getPingDelayMs();
        int acceptableLoss = getAcceptablePacketLossPercentage();
        
        /** See {@link Secure#WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT} */
        int ignoredPingCounter = 0;
        int pingCounter = 0;
        int successCounter = 0;
        
        // No connectivity check needed
        if (numPings == 0) {
            return true;
        }

        // Do the initial pings that we ignore
        for (; ignoredPingCounter < numInitialIgnoredPings; ignoredPingCounter++) {
            if (shouldCancel()) return false;

            boolean dnsAlive = DnsPinger.isDnsReachable(dns, getPingTimeoutMs());
            if (dnsAlive) {
                /*
                 * Successful "ignored" pings are *not* ignored (they count in the total number
                 * of pings), but failures are really ignored.
                 */
                pingCounter++;
                successCounter++;
            }
            
            if (V) {
                Log.v(TAG, (dnsAlive ? "  +" : "  Ignored: -"));
            }

            if (shouldCancel()) return false;
            
            try {
                Thread.sleep(pingDelay);
            } catch (InterruptedException e) {
                Log.w(TAG, "Interrupted while pausing between pings", e);
            }
        }
        
        // Do the pings that we use to measure packet loss
        for (; pingCounter < numPings; pingCounter++) {
            if (shouldCancel()) return false;

            if (DnsPinger.isDnsReachable(dns, getPingTimeoutMs())) {
                successCounter++;
                if (V) {
                    Log.v(TAG, "  +");
                }
            } else {
                if (V) {
                    Log.v(TAG, "  -");
                }
            }

            if (shouldCancel()) return false;
            
            try {
                Thread.sleep(pingDelay);
            } catch (InterruptedException e) {
                Log.w(TAG, "Interrupted while pausing between pings", e);
            }
        }
        
        int packetLossPercentage = 100 * (numPings - successCounter) / numPings;
        if (D) {
            Log.d(TAG, packetLossPercentage
                    + "% packet loss (acceptable is " + acceptableLoss + "%)");
        }
        
        return !shouldCancel() && (packetLossPercentage <= acceptableLoss);
    }

    private boolean backgroundCheckDnsConnectivity() {
        int dns = getDns();
        if (false && V) {
            myLogV("backgroundCheckDnsConnectivity: Background checking " + dns +
                    " for connectivity");
        }
        
        if (dns == -1) {
            if (V) {
                myLogV("backgroundCheckDnsConnectivity: DNS is empty, returning false");
            }
            return false;
        }
        
        return DnsPinger.isDnsReachable(dns, getBackgroundCheckTimeoutMs());
    }
    
    /**
     * Signals the current action to cancel.
     */
    private void cancelCurrentAction() {
        mShouldCancel = true;
    }
    
    /**
     * Helper to check whether to cancel. 
     * 
     * @return Whether to cancel processing the action.
     */
    private boolean shouldCancel() {
        if (V && mShouldCancel) {
            myLogV("shouldCancel: Cancelling");
        }
        
        return mShouldCancel;
    }
    
    // Wi-Fi initiated callbacks (could be executed in another thread)

    /**
     * Called when connected to an AP (this can be the next AP in line, or
     * it can be a completely different network).
     * 
     * @param ssid The SSID of the access point.
     * @param bssid The BSSID of the access point.
     */
    private void onConnected(String ssid, String bssid) {
        if (V) {
            myLogV("onConnected: SSID: " + ssid + ", BSSID: " + bssid);
        }

        /*
         * The current action being processed by the main watchdog thread is now
         * stale, so cancel it.
         */
        cancelCurrentAction();
        
        if ((mSsid == null) || !mSsid.equals(ssid)) {
            /*
             * This is a different network than what the main watchdog thread is
             * processing, dispatch the network change message on the main thread.
             */
            mHandler.dispatchNetworkChanged(ssid);
        }
        
        if (requiresWatchdog(ssid, bssid)) {
            if (D) {
                myLogD(ssid + " (" + bssid + ") requires the watchdog");
            }

            // This access point requires a watchdog, so queue the check on the main thread
            mHandler.checkAp(new AccessPoint(ssid, bssid));
            
        } else {
            if (D) {
                myLogD(ssid + " (" + bssid + ") does not require the watchdog");
            }

            // This access point does not require a watchdog, so queue idle on the main thread
            mHandler.idle();
        }
    }
    
    /**
     * Called when Wi-Fi is enabled.
     */
    private void onEnabled() {
        cancelCurrentAction();
        // Queue a hard-reset of the state on the main thread
        mHandler.reset();
    }
    
    /**
     * Called when disconnected (or some other event similar to being disconnected).
     */
    private void onDisconnected() {
        if (V) {
            myLogV("onDisconnected");
        }
        
        /*
         * Disconnected from an access point, the action being processed by the
         * watchdog thread is now stale, so cancel it.
         */
        cancelCurrentAction();
        // Dispatch the disconnected to the main watchdog thread
        mHandler.dispatchDisconnected();
        // Queue the action to go idle
        mHandler.idle();
    }

    /**
     * Checks whether an access point requires watchdog monitoring.
     * 
     * @param ssid The SSID of the access point.
     * @param bssid The BSSID of the access point.
     * @return Whether the access point/network should be monitored by the
     *         watchdog.
     */
    private boolean requiresWatchdog(String ssid, String bssid) {
        if (V) {
            myLogV("requiresWatchdog: SSID: " + ssid + ", BSSID: " + bssid);
        }
        
        WifiInfo info = null;
        if (ssid == null) {
            /*
             * This is called from a Wi-Fi callback, so assume the WifiInfo does
             * not have stale data.
             */
            info = mWifiManager.getConnectionInfo();
            ssid = info.getSSID();
            if (ssid == null) {
                // It's still null, give up
                if (V) {
                    Log.v(TAG, "  Invalid SSID, returning false");
                }
                return false;
            }
        }
        
        if (TextUtils.isEmpty(bssid)) {
            // Similar as above
            if (info == null) {
                info = mWifiManager.getConnectionInfo();
            }
            bssid = info.getBSSID();
            if (TextUtils.isEmpty(bssid)) {
                // It's still null, give up
                if (V) {
                    Log.v(TAG, "  Invalid BSSID, returning false");
                }
                return false;
            }
        }

        if (!isOnWatchList(ssid)) {
            if (V) {
                Log.v(TAG, "  SSID not on watch list, returning false");
            }
            return false;
        }

        // The watchdog only monitors networks with multiple APs
        if (!hasRequiredNumberOfAps(ssid)) {
            return false;
        }

        return true;
    }

    private boolean isOnWatchList(String ssid) {
        String watchList;

        if (ssid == null || (watchList = getWatchList()) == null) {
            return false;
        }

        String[] list = watchList.split(" *, *");

        for (String name : list) {
            if (ssid.equals(name)) {
                return true;
            }
        }

        return false;
    }
    
    /**
     * Checks if the current scan results have multiple access points with an SSID.
     * 
     * @param ssid The SSID to check.
     * @return Whether the SSID has multiple access points.
     */
    private boolean hasRequiredNumberOfAps(String ssid) {
        List<ScanResult> results = mWifiManager.getScanResults();
        if (results == null) {
            if (V) {
                myLogV("hasRequiredNumberOfAps: Got null scan results, returning false");
            }
            return false;
        }
        
        int numApsRequired = getApCount();
        int numApsFound = 0;
        int resultsSize = results.size();
        for (int i = 0; i < resultsSize; i++) {
            ScanResult result = results.get(i);
            if (result == null) continue;
            if (result.SSID == null) continue;
            
            if (result.SSID.equals(ssid)) {
                numApsFound++;
                
                if (numApsFound >= numApsRequired) {
                    if (V) {
                        myLogV("hasRequiredNumberOfAps: SSID: " + ssid + ", returning true");
                    }
                    return true;
                }
            }
        }
        
        if (V) {
            myLogV("hasRequiredNumberOfAps: SSID: " + ssid + ", returning false");
        }
        return false;
    }
    
    // Watchdog logic (assume all of these methods will be in our main thread)
    
    /**
     * Handles a Wi-Fi network change (for example, from networkA to networkB).
     */
    private void handleNetworkChanged(String ssid) {
        // Set the SSID being monitored to the new SSID 
        mSsid = ssid;
        // Set various state to that when being idle 
        setIdleState(true);
    }
    
    /**
     * Handles checking whether an AP is a "good" AP.  If not, it will be blacklisted.
     * 
     * @param ap The access point to check.
     */
    private void handleCheckAp(AccessPoint ap) {
        // Reset the cancel state since this is the entry point of this action
        mShouldCancel = false;
        
        if (V) {
            myLogV("handleCheckAp: AccessPoint: " + ap);
        }
        
        // Make sure we are not sleeping
        if (mState == WatchdogState.SLEEP) {
            if (V) {
                Log.v(TAG, "  Sleeping (in " + mSsid + "), so returning");
            }
            return;
        }
        
        mState = WatchdogState.CHECKING_AP;
        
        /*
         * Checks to make sure we haven't exceeded the max number of checks
         * we're allowed per network
         */
        mNumApsChecked++;
        if (mNumApsChecked > getMaxApChecks()) {
            if (V) {
                Log.v(TAG, "  Passed the max attempts (" + getMaxApChecks()
                        + "), going to sleep for " + mSsid);
            }
            mHandler.sleep(mSsid);
            return;
        }

        // Do the check
        boolean isApAlive = checkDnsConnectivity();
        
        if (V) {
            Log.v(TAG, "  Is it alive: " + isApAlive);
        }

        // Take action based on results
        if (isApAlive) {
            handleApAlive(ap);
        } else {
            handleApUnresponsive(ap);
        }
    }

    /**
     * Handles the case when an access point is alive.
     * 
     * @param ap The access point.
     */
    private void handleApAlive(AccessPoint ap) {
        // Check whether we are stale and should cancel
        if (shouldCancel()) return;
        // We're satisfied with this AP, so go idle
        setIdleState(false);
        
        if (D) {
            myLogD("AP is alive: " + ap.toString());
        }
        
        // Queue the next action to be a background check
        mHandler.backgroundCheckAp(ap);
    }
    
    /**
     * Handles an unresponsive AP by blacklisting it.
     * 
     * @param ap The access point.
     */
    private void handleApUnresponsive(AccessPoint ap) {
        // Check whether we are stale and should cancel
        if (shouldCancel()) return;
        // This AP is "bad", switch to another
        mState = WatchdogState.SWITCHING_AP;

        if (D) {
            myLogD("AP is dead: " + ap.toString());
        }
        
        // Black list this "bad" AP, this will cause an attempt to connect to another
        blacklistAp(ap.bssid);
    }

    private void blacklistAp(String bssid) {
        if (TextUtils.isEmpty(bssid)) {
            return;
        }
        
        // Before taking action, make sure we should not cancel our processing
        if (shouldCancel()) return;
        
        if (!mWifiStateTracker.addToBlacklist(bssid)) {
            // There's a known bug where this method returns failure on success
            //Log.e(TAG, "Blacklisting " + bssid + " failed");
        }

        if (D) {
            myLogD("Blacklisting " + bssid);
        }
    }

    /**
     * Handles a single background check. If it fails, it should trigger a
     * normal check. If it succeeds, it should queue another background check.
     * 
     * @param ap The access point to do a background check for. If this is no
     *        longer the current AP, it is okay to return without any
     *        processing.
     */
    private void handleBackgroundCheckAp(AccessPoint ap) {
        // Reset the cancel state since this is the entry point of this action
        mShouldCancel = false;
        
        if (false && V) {
            myLogV("handleBackgroundCheckAp: AccessPoint: " + ap);
        }
        
        // Make sure we are not sleeping
        if (mState == WatchdogState.SLEEP) {
            if (V) {
                Log.v(TAG, "  handleBackgroundCheckAp: Sleeping (in " + mSsid + "), so returning");
            }
            return;
        }
        
        // Make sure the AP we're supposed to be background checking is still the active one
        WifiInfo info = mWifiManager.getConnectionInfo();
        if (info.getSSID() == null || !info.getSSID().equals(ap.ssid)) {
            if (V) {
                myLogV("handleBackgroundCheckAp: We are no longer connected to "
                        + ap + ", and instead are on " + info);
            }
            return;
        }
        
        if (info.getBSSID() == null || !info.getBSSID().equals(ap.bssid)) {
            if (V) {
                myLogV("handleBackgroundCheckAp: We are no longer connected to "
                        + ap + ", and instead are on " + info);
            }
            return;
        }

        // Do the check
        boolean isApAlive = backgroundCheckDnsConnectivity();
        
        if (V && !isApAlive) {
            Log.v(TAG, "  handleBackgroundCheckAp: Is it alive: " + isApAlive);
        }

        if (shouldCancel()) {
            return;
        }
        
        // Take action based on results
        if (isApAlive) {
            // Queue another background check
            mHandler.backgroundCheckAp(ap);
            
        } else {
            if (D) {
                myLogD("Background check failed for " + ap.toString());
            }
            
            // Queue a normal check, so it can take proper action
            mHandler.checkAp(ap);
        }
    }
    
    /**
     * Handles going to sleep for this network. Going to sleep means we will not
     * monitor this network anymore.
     * 
     * @param ssid The network that will not be monitored anymore.
     */
    private void handleSleep(String ssid) {
        // Make sure the network we're trying to sleep in is still the current network
        if (ssid != null && ssid.equals(mSsid)) {
            mState = WatchdogState.SLEEP;

            if (D) {
                myLogD("Going to sleep for " + ssid);
            }
            
            /*
             * Before deciding to go to sleep, we may have checked a few APs
             * (and blacklisted them). Clear the blacklist so the AP with best
             * signal is chosen.
             */
            if (!mWifiStateTracker.clearBlacklist()) {
                // There's a known bug where this method returns failure on success
                //Log.e(TAG, "Clearing blacklist failed");
            }
            
            if (V) {
                myLogV("handleSleep: Set state to SLEEP and cleared blacklist");
            }
        }
    }

    /**
     * Handles an access point disconnection.
     */
    private void handleDisconnected() {
        /*
         * We purposefully do not change mSsid to null. This is to handle
         * disconnected followed by connected better (even if there is some
         * duration in between). For example, if the watchdog went to sleep in a
         * network, and then the phone goes to sleep, when the phone wakes up we
         * still want to be in the sleeping state. When the phone went to sleep,
         * we would have gotten a disconnected event which would then set mSsid
         * = null. This is bad, since the following connect would cause us to do
         * the "network is good?" check all over again. */
        
        /* 
         * Set the state as if we were idle (don't come out of sleep, only
         * hard reset and network changed should do that.
         */
        setIdleState(false);
    }

    /**
     * Handles going idle. Idle means we are satisfied with the current state of
     * things, but if a new connection occurs we'll re-evaluate.
     */
    private void handleIdle() {
        // Reset the cancel state since this is the entry point for this action
        mShouldCancel = false;
        
        if (V) {
            myLogV("handleSwitchToIdle");
        }
        
        // If we're sleeping, don't do anything
        if (mState == WatchdogState.SLEEP) {
            Log.v(TAG, "  Sleeping (in " + mSsid + "), so returning");
            return;
        }
        
        // Set the idle state
        setIdleState(false);
        
        if (V) {
            Log.v(TAG, "  Set state to IDLE");
        }
    }
    
    /**
     * Sets the state as if we are going idle.
     */
    private void setIdleState(boolean forceIdleState) {
        // Setting idle state does not kick us out of sleep unless the forceIdleState is set
        if (forceIdleState || (mState != WatchdogState.SLEEP)) {
            mState = WatchdogState.IDLE;
        }
        mNumApsChecked = 0;
    }

    /**
     * Handles a hard reset. A hard reset is rarely used, but when used it
     * should revert anything done by the watchdog monitoring.
     */
    private void handleReset() {
        mWifiStateTracker.clearBlacklist();
        setIdleState(true);
    }
    
    // Inner classes

    /**
     * Possible states for the watchdog to be in.
     */
    private static enum WatchdogState {
        /** The watchdog is currently idle, but it is still responsive to future AP checks in this network. */
        IDLE,
        /** The watchdog is sleeping, so it will not try any AP checks for the network. */
        SLEEP,
        /** The watchdog is currently checking an AP for connectivity. */
        CHECKING_AP,
        /** The watchdog is switching to another AP in the network. */
        SWITCHING_AP
    }

    /**
     * The main thread for the watchdog monitoring. This will be turned into a
     * {@link Looper} thread.
     */
    private class WifiWatchdogThread extends Thread {
        WifiWatchdogThread() {
            super("WifiWatchdogThread");
        }
        
        @Override
        public void run() {
            // Set this thread up so the handler will work on it
            Looper.prepare();
            
            synchronized(WifiWatchdogService.this) {
                mHandler = new WifiWatchdogHandler();

                // Notify that the handler has been created
                WifiWatchdogService.this.notify();
            }
            
            // Listen for messages to the handler
            Looper.loop();
        }
    }

    /**
     * The main thread's handler. There are 'actions', and just general 
     * 'messages'. There should only ever be one 'action' in the queue (aside
     * from the one being processed, if any). There may be multiple messages in
     * the queue. So, actions are replaced by more recent actions, where as
     * messages will be executed for sure. Messages end up being used to just
     * change some state, and not really take any action.
     * <p>
     * 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 {
        /** Check whether the AP is "good".  The object will be an {@link AccessPoint}. */
        static final int ACTION_CHECK_AP = 1;
        /** Go into the idle state. */
        static final int ACTION_IDLE = 2;
        /**
         * Performs a periodic background check whether the AP is still "good".
         * The object will be an {@link AccessPoint}.
         */
        static final int ACTION_BACKGROUND_CHECK_AP = 3;

        /**
         * Go to sleep for the current network. We are conservative with making
         * this a message rather than action. We want to make sure our main
         * thread sees this message, but if it were an action it could be
         * removed from the queue and replaced by another action. The main
         * thread will ensure when it sees the message that the state is still
         * valid for going to sleep.
         * <p>
         * For an explanation of sleep, see {@link android.provider.Settings.Secure#WIFI_WATCHDOG_MAX_AP_CHECKS}.
         */
        static final int MESSAGE_SLEEP = 101;
        /** Disables the watchdog. */
        static final int MESSAGE_DISABLE_WATCHDOG = 102;
        /** The network has changed. */
        static final int MESSAGE_NETWORK_CHANGED = 103;
        /** The current access point has disconnected. */
        static final int MESSAGE_DISCONNECTED = 104;
        /** Performs a hard-reset on the watchdog state. */
        static final int MESSAGE_RESET = 105;
        
        void checkAp(AccessPoint ap) {
            removeAllActions();
            sendMessage(obtainMessage(ACTION_CHECK_AP, ap));
        }
        
        void backgroundCheckAp(AccessPoint ap) {
            if (!isBackgroundCheckEnabled()) return;
            
            removeAllActions();
            sendMessageDelayed(obtainMessage(ACTION_BACKGROUND_CHECK_AP, ap),
                    getBackgroundCheckDelayMs());
        }
        
        void idle() {
            removeAllActions();
            sendMessage(obtainMessage(ACTION_IDLE));
        }
        
        void sleep(String ssid) {
            removeAllActions();
            sendMessage(obtainMessage(MESSAGE_SLEEP, ssid));
        }
        
        void disableWatchdog() {
            removeAllActions();
            sendMessage(obtainMessage(MESSAGE_DISABLE_WATCHDOG));
        }
        
        void dispatchNetworkChanged(String ssid) {
            removeAllActions();
            sendMessage(obtainMessage(MESSAGE_NETWORK_CHANGED, ssid));
        }

        void dispatchDisconnected() {
            removeAllActions();
            sendMessage(obtainMessage(MESSAGE_DISCONNECTED));
        }

        void reset() {
            removeAllActions();
            sendMessage(obtainMessage(MESSAGE_RESET));
        }
        
        private void removeAllActions() {
            removeMessages(ACTION_CHECK_AP);
            removeMessages(ACTION_IDLE);
            removeMessages(ACTION_BACKGROUND_CHECK_AP);
        }
        
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MESSAGE_NETWORK_CHANGED:
                    handleNetworkChanged((String) msg.obj);
                    break;
                case ACTION_CHECK_AP:
                    handleCheckAp((AccessPoint) msg.obj);
                    break;
                case ACTION_BACKGROUND_CHECK_AP:
                    handleBackgroundCheckAp((AccessPoint) msg.obj);
                    break;
                case MESSAGE_SLEEP:
                    handleSleep((String) msg.obj);
                    break;
                case ACTION_IDLE:
                    handleIdle();
                    break;
                case MESSAGE_DISABLE_WATCHDOG:
                    handleIdle();
                    break;
                case MESSAGE_DISCONNECTED:
                    handleDisconnected();
                    break;
                case MESSAGE_RESET:
                    handleReset();
                    break;
            }
        }
    }

    /**
     * Receives Wi-Fi broadcasts.
     * <p>
     * There is little logic in this class, instead methods of the form "on___"
     * are called in the {@link WifiWatchdogService}.
     */
    private BroadcastReceiver mReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
                handleNetworkStateChanged(
                        (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO));
            } else if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
                handleSupplicantConnectionChanged(
                        intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false));
            } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
                handleWifiStateChanged(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
                        WifiManager.WIFI_STATE_UNKNOWN));
            }
        }

        private void handleNetworkStateChanged(NetworkInfo info) {
            if (V) {
                myLogV("Receiver.handleNetworkStateChanged: NetworkInfo: "
                        + info);
            }
            
            switch (info.getState()) {
                case CONNECTED:
                    WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
                    if (wifiInfo.getSSID() == null || wifiInfo.getBSSID() == null) {
                        if (V) {
                            myLogV("handleNetworkStateChanged: Got connected event but SSID or BSSID are null. SSID: "
                                + wifiInfo.getSSID()
                                + ", BSSID: "
                                + wifiInfo.getBSSID() + ", ignoring event");
                        }
                        return;
                    }
                    onConnected(wifiInfo.getSSID(), wifiInfo.getBSSID());
                    break;

                case DISCONNECTED:
                    onDisconnected();
                    break;
            }
        }

        private void handleSupplicantConnectionChanged(boolean connected) {
            if (!connected) {
                onDisconnected();
            }
        }
        
        private void handleWifiStateChanged(int wifiState) {
            if (wifiState == WifiManager.WIFI_STATE_DISABLED) {
                onDisconnected();
            } else if (wifiState == WifiManager.WIFI_STATE_ENABLED) {
                onEnabled();
            }
        }
    };

    /**
     * Describes an access point by its SSID and BSSID.
     */
    private static class AccessPoint {
        String ssid;
        String bssid;
        
        AccessPoint(String ssid, String bssid) {
            this.ssid = ssid;
            this.bssid = bssid;
        }

        private boolean hasNull() {
            return ssid == null || bssid == null;
        }
        
        @Override
        public boolean equals(Object o) {
            if (!(o instanceof AccessPoint)) return false;
            AccessPoint otherAp = (AccessPoint) o;
            boolean iHaveNull = hasNull();
            // Either we both have a null, or our SSIDs and BSSIDs are equal
            return (iHaveNull && otherAp.hasNull()) || 
                    (otherAp.bssid != null && ssid.equals(otherAp.ssid)
                    && bssid.equals(otherAp.bssid));
        }
        
        @Override
        public int hashCode() {
            if (ssid == null || bssid == null) return 0;
            return ssid.hashCode() + bssid.hashCode();
        }

        @Override
        public String toString() {
            return ssid + " (" + bssid + ")";
        }
    }

    /**
     * Performs a simple DNS "ping" by sending a "server status" query packet to
     * the DNS server. As long as the server replies, we consider it a success.
     * <p>
     * We do not use a simple hostname lookup because that could be cached and
     * the API may not differentiate between a time out and a failure lookup
     * (which we really care about).
     */
    private static class DnsPinger {
        
        /** Number of bytes for the query */
        private static final int DNS_QUERY_BASE_SIZE = 33;
        
        /** The DNS port */
        private static final int DNS_PORT = 53;
        
        /** Used to generate IDs */
        private static Random sRandom = new Random();
        
        static boolean isDnsReachable(int dns, int timeout) {
            try {
                DatagramSocket socket = new DatagramSocket();
                
                // Set some socket properties
                socket.setSoTimeout(timeout);
                
                byte[] buf = new byte[DNS_QUERY_BASE_SIZE];
                fillQuery(buf);
                
                // Send the DNS query
                byte parts[] = new byte[4];
                parts[0] = (byte)(dns & 0xff);
                parts[1] = (byte)((dns >> 8) & 0xff);
                parts[2] = (byte)((dns >> 16) & 0xff);
                parts[3] = (byte)((dns >> 24) & 0xff);

                InetAddress dnsAddress = InetAddress.getByAddress(parts);
                DatagramPacket packet = new DatagramPacket(buf,
                        buf.length, dnsAddress, DNS_PORT);
                socket.send(packet);
                
                // Wait for reply (blocks for the above timeout)
                DatagramPacket replyPacket = new DatagramPacket(buf, buf.length);
                socket.receive(replyPacket);

                // If a timeout occurred, an exception would have been thrown.  We got a reply!
                return true;
                
            } catch (SocketException e) {
                if (V) {
                    Log.v(TAG, "DnsPinger.isReachable received SocketException", e);
                }
                return false;
                
            } catch (UnknownHostException e) {
                if (V) {
                    Log.v(TAG, "DnsPinger.isReachable is unable to resolve the DNS host", e);
                }
                return false;

            } catch (SocketTimeoutException e) {
                return false;
                
            } catch (IOException e) {
                if (V) {
                    Log.v(TAG, "DnsPinger.isReachable got an IOException", e);
                }
                return false;
                
            } catch (Exception e) {
                if (V || Config.LOGD) {
                    Log.d(TAG, "DnsPinger.isReachable got an unknown exception", e);
                }
                return false;
            }
        }
        
        private static void fillQuery(byte[] buf) {

            /*
             * See RFC2929 (though the bit tables in there are misleading for
             * us. For example, the recursion desired bit is the 0th bit for us,
             * but looking there it would appear as the 7th bit of the byte
             */

            // Make sure it's all zeroed out
            for (int i = 0; i < buf.length; i++) buf[i] = 0;

            // Form a query for www.android.com
            
            // [0-1] bytes are an ID, generate random ID for this query
            buf[0] = (byte) sRandom.nextInt(256); 
            buf[1] = (byte) sRandom.nextInt(256); 
            
            // [2-3] bytes are for flags.
            buf[2] = 1; // Recursion desired

            // [4-5] bytes are for the query count
            buf[5] = 1; // One query 
            
            // [6-7] [8-9] [10-11] are all counts of other fields we don't use

            // [12-15] for www
            writeString(buf, 12, "www");
            
            // [16-23] for android
            writeString(buf, 16, "android");
            
            // [24-27] for com
            writeString(buf, 24, "com");
            
            // [29-30] bytes are for QTYPE, set to 1 
            buf[30] = 1;

            // [31-32] bytes are for QCLASS, set to 1 
            buf[32] = 1;
        }
        
        private static void writeString(byte[] buf, int startPos, String string) {
            int pos = startPos;
            
            // Write the length first
            buf[pos++] = (byte) string.length();
            for (int i = 0; i < string.length(); i++) {
                buf[pos++] = (byte) string.charAt(i);
            }
        }
    }
}
