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/data/fonts/fallback_fonts.xml b/data/fonts/fallback_fonts.xml
new file mode 100644
index 0000000..c0d9153
--- /dev/null
+++ b/data/fonts/fallback_fonts.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Fallback Fonts
+
+    This file specifies the fonts, and the priority order, that will be searched for any
+    glyphs not handled by the default fonts specified in /system/etc/system_fonts.xml.
+    Each entry consists of a family tag and a list of files (file names) which support that
+    family. The fonts for each family are listed in the order of the styles that they
+    handle (the order is: regular, bold, italic, and bold-italic). The order in which the
+    families are listed in this file represents the order in which these fallback fonts
+    will be searched for glyphs that are not supported by the default system fonts (which are
+    found in /system/etc/system_fonts.xml).
+
+    Note that there is not nameset for fallback fonts, unlike the fonts specified in
+    system_fonts.xml. The ability to support specific names in fallback fonts may be supported
+    in the future. For now, the lack of files entries here is an indicator to the system that
+    these are fallback fonts, instead of default named system fonts.
+
+    There is another optional file in /vendor/etc/fallback_fonts.xml. That file can be used to
+    provide references to other font families that should be used in addition to the default
+    fallback fonts. That file can also specify the order in which the fallback fonts should be
+    searched, to ensure that a vendor-provided font will be used before another fallback font
+    which happens to handle the same glyph.
+-->
+<familyset>
+    <family>
+        <fileset>
+            <file>DroidSansArabic.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>DroidSansHebrew-Regular.ttf</file>
+            <file>DroidSansHebrew-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>DroidSansThai.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>DroidSansFallback.ttf</file>
+        </fileset>
+    </family>
+</familyset>
diff --git a/data/fonts/fonts.mk b/data/fonts/fonts.mk
index d222c0b..57a1bab 100644
--- a/data/fonts/fonts.mk
+++ b/data/fonts/fonts.mk
@@ -30,4 +30,6 @@
     frameworks/base/data/fonts/DroidSansFallback.ttf:system/fonts/DroidSansFallback.ttf \
     frameworks/base/data/fonts/AndroidClock.ttf:system/fonts/AndroidClock.ttf \
     frameworks/base/data/fonts/AndroidClock_Highlight.ttf:system/fonts/AndroidClock_Highlight.ttf \
-    frameworks/base/data/fonts/AndroidClock_Solid.ttf:system/fonts/AndroidClock_Solid.ttf
+    frameworks/base/data/fonts/AndroidClock_Solid.ttf:system/fonts/AndroidClock_Solid.ttf \
+    frameworks/base/data/fonts/system_fonts.xml:system/etc/system_fonts.xml \
+    frameworks/base/data/fonts/fallback_fonts.xml:system/etc/fallback_fonts.xml
diff --git a/data/fonts/system_fonts.xml b/data/fonts/system_fonts.xml
new file mode 100644
index 0000000..8d8d020
--- /dev/null
+++ b/data/fonts/system_fonts.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    System Fonts
+
+    This file lists the font families that will be used by default for all supported glyphs.
+    Each entry consists of a family, various names that are supported by that family, and
+    up to four font files. The font files are listed in the order of the styles which they
+    support: regular, bold, italic and bold-italic. If less than four styles are listed, then
+    the styles with no associated font file will be supported by the other font files listed.
+
+    The first family is also the default font, which handles font request that have not specified
+    specific font names.
+
+    Any glyph that is not handled by the system fonts will cause a search of the fallback fonts.
+    The default fallback fonts are specified in the file /system/etc/fallback_fonts.xml, and there
+    is an optional file which may be supplied by vendors to specify other fallback fonts to use
+    in /vendor/etc/fallback_fonts.xml.
+-->
+<familyset>
+
+    <family>
+        <nameset>
+            <name>sans-serif</name>
+            <name>arial</name>
+            <name>helvetica</name>
+            <name>tahoma</name>
+            <name>verdana</name>
+        </nameset>
+        <fileset>
+            <file>DroidSans.ttf</file>
+            <file>DroidSans-Bold.ttf</file>
+        </fileset>
+    </family>
+
+    <family>
+        <nameset>
+            <name>serif</name>
+            <name>times</name>
+            <name>times new roman</name>
+            <name>palatino</name>
+            <name>georgia</name>
+            <name>baskerville</name>
+            <name>goudy</name>
+            <name>fantasy</name>
+            <name>cursive</name>
+            <name>ITC Stone Serif</name>
+        </nameset>
+        <fileset>
+            <file>DroidSerif-Regular.ttf</file>
+            <file>DroidSerif-Bold.ttf</file>
+            <file>DroidSerif-Italic.ttf</file>
+            <file>DroidSerif-BoldItalic.ttf</file>
+        </fileset>
+    </family>
+
+    <family>
+        <nameset>
+            <name>monospace</name>
+            <name>courier</name>
+            <name>courier new</name>
+            <name>monaco</name>
+        </nameset>
+        <fileset>
+            <file>DroidSansMono.ttf</file>
+        </fileset>
+    </family>
+
+</familyset>
diff --git a/data/fonts/vendor_fonts.xml b/data/fonts/vendor_fonts.xml
new file mode 100644
index 0000000..fe51fd27
--- /dev/null
+++ b/data/fonts/vendor_fonts.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Vendor-provided fallback fonts
+
+    This file can be edited to add references to fonts that are not installed or referenced in the
+    default system. The file should then be placed in /vendor/etc/fallback_fonts.xml.
+
+    For example, vendors might want to build configurations for locales that are
+    better served by fonts which either handle glyphs not supported in the default fonts or which
+    handle these glyphs differently than the default fallback fonts.
+    Each entry in this list is a "family", which consists of a list of "files"
+    (the filenames for that family). The files objects are
+    provided in the order of the styles supported for that family: regular, bold, italic, and
+    bold-italic. Only providing one font means that all styles will be rendered with that font.
+    Providing two means that these two fonts will render regular and bold fonts (italics will
+    be mapped to these two fonts).
+
+    There is also an optional "order" attribute on the Family tag. This specifies the index at
+    which that family of fonts should be inserted in the fallback font list, where the
+    default fallback fonts on the system (in /system/etc/fallback_fonts.xml) start at index 0.
+    If no 'order' attribute is supplied, that family will be inserted either at the end of the
+    current fallback list (if no order was supplied for any previous family in this file) or
+    after the previous family (if there was an order specified previously). Typically, vendors
+    may want to supply an order for the first family that puts this set of fonts at the appropriate
+    place in the overall fallback fonts. The order of this list determines which fallback font
+    will be used to support any glyphs that are not handled by the default system fonts.
+
+    The sample configuration below is an example of how one might provide two families of fonts
+    that get inserted at the first and second (0  and 1) position in the overall fallback fonts.
+
+    See /system/etc/system_fonts.xml and /system/etc/fallback_fonts.xml for more information
+    and to understand the order in which the default system fonts are loaded and structured for
+    lookup.
+-->
+
+<!-- Sample fallback font additions to the default fallback list. These fonts will be added
+    to the top two positions of the fallback list, since the first has an order of 0. -->
+<!--
+<familyset>
+    <family order="0">
+        <fileset>
+            <file>MyFont.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>MyOtherFont.ttf</file>
+        </fileset>
+    </family>
+</familyset>
+-->
\ No newline at end of file
diff --git a/media/libstagefright/XINGSeeker.cpp b/media/libstagefright/XINGSeeker.cpp
index 0d0d6c2..2091381 100644
--- a/media/libstagefright/XINGSeeker.cpp
+++ b/media/libstagefright/XINGSeeker.cpp
@@ -24,8 +24,8 @@
 static bool parse_xing_header(
         const sp<DataSource> &source, off64_t first_frame_pos,
         int32_t *frame_number = NULL, int32_t *byte_number = NULL,
-        char *table_of_contents = NULL, int32_t *quality_indicator = NULL,
-        int64_t *duration = NULL);
+        unsigned char *table_of_contents = NULL,
+        int32_t *quality_indicator = NULL, int64_t *duration = NULL);
 
 // static
 sp<XINGSeeker> XINGSeeker::CreateFromSource(
@@ -94,7 +94,7 @@
 static bool parse_xing_header(
         const sp<DataSource> &source, off64_t first_frame_pos,
         int32_t *frame_number, int32_t *byte_number,
-        char *table_of_contents, int32_t *quality_indicator,
+        unsigned char *table_of_contents, int32_t *quality_indicator,
         int64_t *duration) {
     if (frame_number) {
         *frame_number = 0;
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index 8ecc17c..ca61b3d 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -36,11 +36,10 @@
 
 #include <ctype.h>
 #include <openssl/aes.h>
+#include <openssl/md5.h>
 
 namespace android {
 
-const int64_t LiveSession::kMaxPlaylistAgeUs = 15000000ll;
-
 LiveSession::LiveSession(uint32_t flags, bool uidValid, uid_t uid)
     : mFlags(flags),
       mUIDValid(uidValid),
@@ -59,7 +58,8 @@
       mDurationUs(-1),
       mSeekDone(false),
       mDisconnectPending(false),
-      mMonitorQueueGeneration(0) {
+      mMonitorQueueGeneration(0),
+      mRefreshState(INITIAL_MINIMUM_RELOAD_DELAY) {
     if (mUIDValid) {
         mHTTPDataSource->setUID(mUID);
     }
@@ -175,7 +175,8 @@
 
     mMasterURL = url;
 
-    sp<M3UParser> playlist = fetchPlaylist(url.c_str());
+    bool dummy;
+    sp<M3UParser> playlist = fetchPlaylist(url.c_str(), &dummy);
 
     if (playlist == NULL) {
         LOGE("unable to fetch master playlist '%s'.", url.c_str());
@@ -289,7 +290,9 @@
     return OK;
 }
 
-sp<M3UParser> LiveSession::fetchPlaylist(const char *url) {
+sp<M3UParser> LiveSession::fetchPlaylist(const char *url, bool *unchanged) {
+    *unchanged = false;
+
     sp<ABuffer> buffer;
     status_t err = fetchFile(url, &buffer);
 
@@ -297,6 +300,38 @@
         return NULL;
     }
 
+    // MD5 functionality is not available on the simulator, treat all
+    // playlists as changed.
+
+#if defined(HAVE_ANDROID_OS)
+    uint8_t hash[16];
+
+    MD5_CTX m;
+    MD5_Init(&m);
+    MD5_Update(&m, buffer->data(), buffer->size());
+
+    MD5_Final(hash, &m);
+
+    if (mPlaylist != NULL && !memcmp(hash, mPlaylistHash, 16)) {
+        // playlist unchanged
+
+        if (mRefreshState != THIRD_UNCHANGED_RELOAD_ATTEMPT) {
+            mRefreshState = (RefreshState)(mRefreshState + 1);
+        }
+
+        *unchanged = true;
+
+        LOGV("Playlist unchanged, refresh state is now %d",
+             (int)mRefreshState);
+
+        return NULL;
+    }
+
+    memcpy(mPlaylistHash, hash, sizeof(hash));
+
+    mRefreshState = INITIAL_MINIMUM_RELOAD_DELAY;
+#endif
+
     sp<M3UParser> playlist =
         new M3UParser(url, buffer->data(), buffer->size());
 
@@ -384,6 +419,63 @@
     return index;
 }
 
+bool LiveSession::timeToRefreshPlaylist(int64_t nowUs) const {
+    if (mPlaylist == NULL) {
+        CHECK_EQ((int)mRefreshState, (int)INITIAL_MINIMUM_RELOAD_DELAY);
+        return true;
+    }
+
+    int32_t targetDurationSecs;
+    CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs));
+
+    int64_t targetDurationUs = targetDurationSecs * 1000000ll;
+
+    int64_t minPlaylistAgeUs;
+
+    switch (mRefreshState) {
+        case INITIAL_MINIMUM_RELOAD_DELAY:
+        {
+            size_t n = mPlaylist->size();
+            if (n > 0) {
+                sp<AMessage> itemMeta;
+                CHECK(mPlaylist->itemAt(n - 1, NULL /* uri */, &itemMeta));
+
+                int64_t itemDurationUs;
+                CHECK(itemMeta->findInt64("durationUs", &itemDurationUs));
+
+                minPlaylistAgeUs = itemDurationUs;
+                break;
+            }
+
+            // fall through
+        }
+
+        case FIRST_UNCHANGED_RELOAD_ATTEMPT:
+        {
+            minPlaylistAgeUs = targetDurationUs / 2;
+            break;
+        }
+
+        case SECOND_UNCHANGED_RELOAD_ATTEMPT:
+        {
+            minPlaylistAgeUs = (targetDurationUs * 3) / 2;
+            break;
+        }
+
+        case THIRD_UNCHANGED_RELOAD_ATTEMPT:
+        {
+            minPlaylistAgeUs = targetDurationUs * 3;
+            break;
+        }
+
+        default:
+            TRESPASS();
+            break;
+    }
+
+    return mLastPlaylistFetchTimeUs + minPlaylistAgeUs <= nowUs;
+}
+
 void LiveSession::onDownloadNext() {
     size_t bandwidthIndex = getBandwidthIndex();
 
@@ -392,8 +484,7 @@
 
     if (mLastPlaylistFetchTimeUs < 0
             || (ssize_t)bandwidthIndex != mPrevBandwidthIndex
-            || (!mPlaylist->isComplete()
-                && mLastPlaylistFetchTimeUs + kMaxPlaylistAgeUs <= nowUs)) {
+            || (!mPlaylist->isComplete() && timeToRefreshPlaylist(nowUs))) {
         AString url;
         if (mBandwidthItems.size() > 0) {
             url = mBandwidthItems.editItemAt(bandwidthIndex).mURI;
@@ -403,11 +494,19 @@
 
         bool firstTime = (mPlaylist == NULL);
 
-        mPlaylist = fetchPlaylist(url.c_str());
-        if (mPlaylist == NULL) {
-            LOGE("failed to load playlist at url '%s'", url.c_str());
-            mDataSource->queueEOS(ERROR_IO);
-            return;
+        bool unchanged;
+        sp<M3UParser> playlist = fetchPlaylist(url.c_str(), &unchanged);
+        if (playlist == NULL) {
+            if (unchanged) {
+                // We succeeded in fetching the playlist, but it was
+                // unchanged from the last time we tried.
+            } else {
+                LOGE("failed to load playlist at url '%s'", url.c_str());
+                mDataSource->queueEOS(ERROR_IO);
+                return;
+            }
+        } else {
+            mPlaylist = playlist;
         }
 
         if (firstTime) {
diff --git a/media/libstagefright/include/LiveSession.h b/media/libstagefright/include/LiveSession.h
index 188ef5e..116ed0e 100644
--- a/media/libstagefright/include/LiveSession.h
+++ b/media/libstagefright/include/LiveSession.h
@@ -62,8 +62,6 @@
         kMaxNumRetries         = 5,
     };
 
-    static const int64_t kMaxPlaylistAgeUs;
-
     enum {
         kWhatConnect        = 'conn',
         kWhatDisconnect     = 'disc',
@@ -106,6 +104,16 @@
 
     int32_t mMonitorQueueGeneration;
 
+    enum RefreshState {
+        INITIAL_MINIMUM_RELOAD_DELAY,
+        FIRST_UNCHANGED_RELOAD_ATTEMPT,
+        SECOND_UNCHANGED_RELOAD_ATTEMPT,
+        THIRD_UNCHANGED_RELOAD_ATTEMPT
+    };
+    RefreshState mRefreshState;
+
+    uint8_t mPlaylistHash[16];
+
     void onConnect(const sp<AMessage> &msg);
     void onDisconnect();
     void onDownloadNext();
@@ -113,7 +121,7 @@
     void onSeek(const sp<AMessage> &msg);
 
     status_t fetchFile(const char *url, sp<ABuffer> *out);
-    sp<M3UParser> fetchPlaylist(const char *url);
+    sp<M3UParser> fetchPlaylist(const char *url, bool *unchanged);
     size_t getBandwidthIndex();
 
     status_t decryptBuffer(
@@ -121,6 +129,8 @@
 
     void postMonitorQueue(int64_t delayUs = 0);
 
+    bool timeToRefreshPlaylist(int64_t nowUs) const;
+
     static int SortByBandwidth(const BandwidthItem *, const BandwidthItem *);
 
     DISALLOW_EVIL_CONSTRUCTORS(LiveSession);
diff --git a/media/libstagefright/include/XINGSeeker.h b/media/libstagefright/include/XINGSeeker.h
index d5a484e..ec5bd9b 100644
--- a/media/libstagefright/include/XINGSeeker.h
+++ b/media/libstagefright/include/XINGSeeker.h
@@ -37,7 +37,7 @@
     int32_t mSizeBytes;
 
     // TOC entries in XING header. Skip the first one since it's always 0.
-    char mTableOfContents[99];
+    unsigned char mTableOfContents[99];
 
     XINGSeeker();
 
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/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index b0881a4..680814c 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1551,8 +1551,18 @@
          * Dump SurfaceFlinger global state
          */
 
-        snprintf(buffer, SIZE, "SurfaceFlinger global state\n");
+        snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
         result.append(buffer);
+
+        const GLExtensions& extensions(GLExtensions::getInstance());
+        snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
+                extensions.getVendor(),
+                extensions.getRenderer(),
+                extensions.getVersion());
+        result.append(buffer);
+        snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
+        result.append(buffer);
+
         mWormholeRegion.dump(result, "WormholeRegion");
         const DisplayHardware& hw(graphicPlane(0).displayHardware());
         snprintf(buffer, SIZE,
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;
+        }
+    }
+}
