diff --git a/Android.mk b/Android.mk
index 48bce25..8692412 100644
--- a/Android.mk
+++ b/Android.mk
@@ -6,8 +6,9 @@
     guava \
     jsr305 \
 
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+# Don't build anything, the needed system APIs have been removed.
+#LOCAL_SRC_FILES := $(call all-java-files-under, src)
+#LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := NetworkRecommendation
 LOCAL_CERTIFICATE := platform
@@ -24,4 +25,4 @@
 include $(BUILD_PACKAGE)
 
 # This finds and builds the test apk as well, so a single make does both.
-include $(call all-makefiles-under,$(LOCAL_PATH))
+#include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 881c8c5..3c61f98 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -27,12 +27,17 @@
     <uses-permission android:name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME"/>
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
 
-    <application android:allowBackup="false"
+    <application android:name=".NetworkRecommendationApp"
+                 android:allowBackup="false"
                  android:directBootAware="true">
 
         <!-- Only the platform can bind to this service -->
-        <service android:name=".DefaultNetworkRecommendationService"
+        <service android:name=".NetworkRecommendationService"
                  android:permission="android.permission.BIND_NETWORK_RECOMMENDATION_SERVICE">
+            <meta-data android:name="android.net.scoring.recommendation_service_label"
+                       android:value="@string/network_recommendation_service_label"/>
+            <meta-data android:name="android.net.wifi.notification_channel_id_network_available"
+                       android:value="com.android.networkrecommendation.Notifications.WifiMessageGroup.NetworkAvailableChannel" />
             <intent-filter>
                 <action android:name="android.net.action.RECOMMEND_NETWORKS" />
             </intent-filter>
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 2673295..c0da365 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,5 +1,5 @@
 [Hook Scripts]
-checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --sha ${PREUPLOAD_COMMIT}
+google_java_format = true
 
 [Builtin Hooks]
 commit_msg_bug_field = true
diff --git a/proguard.flags b/proguard.flags
index f925f1f..2d236f7 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -1 +1 @@
--keep class com.android.networkrecommendation.DefaultNetworkRecommendationService* { *; }
+-keep class com.android.networkrecommendation.NetworkRecommendationService* { *; }
diff --git a/res/drawable/ic_signal_wifi_statusbar_not_connected.xml b/res/drawable/ic_signal_wifi_statusbar_not_connected.xml
new file mode 100644
index 0000000..d74c31b
--- /dev/null
+++ b/res/drawable/ic_signal_wifi_statusbar_not_connected.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2017 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="26dp"
+    android:height="24dp"
+    android:viewportWidth="26"
+    android:viewportHeight="24">
+
+    <path android:pathData="M0 0h26v24H0z" />
+    <path android:fillColor="#FFFFFF"
+          android:fillAlpha=".3"
+          android:pathData="M21 8.5c.85 0 1.64 .23 2.34 .62 l2.24-2.79C25.1 5.96 20.26 2 13 2S.9 5.96 .42 6.32l12.57 15.66 .01 .02 .01 -.01 4.21-5.24c-.76-.87-1.22-2-1.22-3.25 0-2.76 2.24-5 5-5z" />
+    <path android:fillColor="#FFFFFF"
+          android:pathData="M21 10c-1.93 0-3.5 1.57-3.5 3.5h1.75c0-.97 .78 -1.75 1.75-1.75s1.75 .78 1.75 1.75c0 .48-.2 .92 -.51 1.24l-1.09 1.1c-.63 .63 -1.02 1.51-1.02 2.47v.44h1.75c0-1.31 .39 -1.84 1.03-2.47l.78-.8c.5-.5 .82 -1.2 .82 -1.97C24.5 11.57 22.93 10 21 10zm-.95 11.95h1.9v-1.9h-1.9v1.9z" />
+</vector>
+
diff --git a/res/values/config.xml b/res/values/config.xml
index 3762e90..4167ebd 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -18,9 +18,13 @@
     <integer translatable="false" name="config_netrec_5GHz_preference_boost_factor">40</integer>
     <integer translatable="false" name="config_netrec_RSSI_SCORE_OFFSET">85</integer>
     <integer translatable="false" name="config_netrec_RSSI_SCORE_SLOPE">4</integer>
+    <integer translatable="false" name="config_netrec_SAME_BSSID_AWARD">24</integer>
+    <integer translatable="false" name="config_netrec_LAST_SELECTION_AWARD">480</integer>
     <integer translatable="false" name="config_netrec_PASSPOINT_SECURITY_AWARD">40</integer>
     <integer translatable="false" name="config_netrec_SECURITY_AWARD">80</integer>
     <integer translatable="false" name="config_netrec_wifi_score_low_rssi_threshold_5GHz">-70</integer>
     <integer translatable="false" name="config_netrec_wifi_score_low_rssi_threshold_24GHz">-73</integer>
     <integer translatable="false" name="config_netrec_wifi_score_good_rssi_threshold_24GHz">-60</integer>
+    <integer translatable="false" name="config_netrec_score_good_rssi_threshold">-60</integer>
+    <integer translatable="false" name="config_netrec_current_network_boost">16</integer>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index c70c1d2..e208b4c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -15,19 +15,36 @@
 -->
 
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- A notification is shown when there is a high quality open wireless network nearby.  This is the notification's title. -->
-    <string name="wifi_available">Connect to Wi\u2011Fi Network</string>
+    <!-- The service label for network recommendation service. [CHAR LIMIT=40] -->
+    <string name="network_recommendation_service_label">System default</string>
 
-    <!-- A notification is shown when there is a high quality open wireless network nearby. These are the different notification actions. -->
-    <string name="wifi_available_options">Options</string>
-    <string name="wifi_available_connect">Connect</string>
-    <string name="wifi_available_connecting">Connecting</string>
-    <string name="wifi_available_connected">Connected</string>
-    <string name="wifi_available_failed">FAILED TO CONNECT</string>
+    <!-- Notification title when there is a high quality open wireless network nearby.-->
+    <string name="wifi_available_title">Connect to open Wi\u2011Fi network</string>
+    <!-- Notification title when the system is connecting to a high quality open network. -->
+    <string name="wifi_available_title_connecting">Connecting to open Wi\u2011Fi network</string>
+    <!-- Notification title when the system has connected to the high quality open network. -->
+    <string name="wifi_available_title_connected">Connected to Wi\u2011Fi network</string>
+    <!-- Notification title when the system failed to connect to the high quality open network. -->
+    <string name="wifi_available_title_failed">Couldn\u0027t connect to Wi\u2011Fi network</string>
+    <!-- Notification content informing the user that tapping on this notification will open the wifi picker. -->
+    <string name="wifi_available_content_failed">Tap to see all networks</string>
 
-    <string name="android_system_label">Android System</string>
+    <!-- Notification action name for connecting to the network specified in the notification body. -->
+    <string name="wifi_available_action_connect">Connect</string>
+    <!-- Notification action name for opening the wifi picker, showing the user all the nearby networks. -->
+    <string name="wifi_available_action_all_networks">All Networks</string>
 
     <!-- A notification is shown when Wi-Fi Wakeup enables Wi-Fi. -->
-    <string name="wifi_wakeup_enabled_notification_title">Wi\u2011Fi was turned on automatically</string>
-    <string name="wifi_wakeup_enabled_notification_context">"Wi\u2011Fi turned on because you are near saved network, %1$s."</string>
+    <string name="wifi_wakeup_enabled_notification_title">Wi\u2011Fi turned on automatically</string>
+    <string name="wifi_wakeup_enabled_notification_context">You\u0027re near a saved network: %1$s</string>
+
+    <!-- Text used to indicate that a connection attempt is ongoing [CHAR LIMIT=20] -->
+    <string name="common_connecting">Connecting&#8230;</string>
+
+    <!-- Name of the notification channel group of our Wi-Fi messages -->
+    <string name="notification_channel_group_name">Wi\u2011Fi messages</string>
+    <!-- Name of the notification channel for a notification shown when there is a high quality open wireless network nearby. -->
+    <string name="notification_channel_wakeup_name">Wi\u2011Fi turned on</string>
+    <!-- Name of the notification channel for a notification shown when Wi-Fi Wakeup enables Wi-Fi.. -->
+    <string name="notification_channel_network_available">Network available</string>
 </resources>
diff --git a/src/com/android/networkrecommendation/Constants.java b/src/com/android/networkrecommendation/Constants.java
new file mode 100644
index 0000000..d680f9f
--- /dev/null
+++ b/src/com/android/networkrecommendation/Constants.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2016 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.networkrecommendation;
+
+/**
+ * Created by jlapenna on 2/14/17.
+ */
+public final class Constants {
+
+    public static final String TAG = "NetRec";
+
+    private Constants() {}
+}
diff --git a/src/com/android/networkrecommendation/DefaultNetworkRecommendationProvider.java b/src/com/android/networkrecommendation/DefaultNetworkRecommendationProvider.java
index 355d2b8..2f8afa8 100644
--- a/src/com/android/networkrecommendation/DefaultNetworkRecommendationProvider.java
+++ b/src/com/android/networkrecommendation/DefaultNetworkRecommendationProvider.java
@@ -16,6 +16,7 @@
 
 package com.android.networkrecommendation;
 
+import android.content.Context;
 import android.net.NetworkKey;
 import android.net.NetworkRecommendationProvider;
 import android.net.NetworkScoreManager;
@@ -27,16 +28,18 @@
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration;
 import android.os.Bundle;
-import android.os.Handler;
 import android.support.annotation.VisibleForTesting;
 import android.text.TextUtils;
 import android.util.ArrayMap;
-import android.util.Log;
+
+import com.android.networkrecommendation.util.Blog;
+import com.android.networkrecommendation.util.SsidUtil;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.Executor;
 
 import javax.annotation.concurrent.GuardedBy;
 
@@ -49,13 +52,13 @@
  * <p>This recommender is not yet recommended for non-development devices.
  *
  * <p>To debug:
- * $ adb shell dumpsys activity service DefaultNetworkRecommendationService
+ * $ adb shell dumpsys activity service NetworkRecommendationService
  *
  * <p>Clear stored scores:
- * $ adb shell dumpsys activity service DefaultNetworkRecommendationService clear
+ * $ adb shell dumpsys activity service NetworkRecommendationService clear
  *
  * <p>Score a network:
- * $ adb shell dumpsys activity service DefaultNetworkRecommendationService addScore $SCORE
+ * $ adb shell dumpsys activity service NetworkRecommendationService addScore $SCORE
  *
  * <p>SCORE: "Quoted SSID",bssid|$RSSI_CURVE|metered|captivePortal|BADGE
  *
@@ -67,17 +70,17 @@
  *
  * <p>All commands should be executed on one line, no spaces between each line of the command..
  * <p>Eg, A high quality, paid network with captive portal:
- * $ adb shell dumpsys activity service DefaultNetworkRecommendationService addScore \
+ * $ adb shell dumpsys activity service NetworkRecommendationService addScore \
  * '\"Metered\",aa:bb:cc:dd:ee:ff\|
  * 10,-128,-128,-128,-128,-128,-128,-128,-128,27,27,27,27,27,-128\|1\|1'
  *
  * <p>Eg, A high quality, unmetered network with captive portal:
- * $ adb shell dumpsys activity service DefaultNetworkRecommendationService addScore \
+ * $ adb shell dumpsys activity service NetworkRecommendationService addScore \
  * '\"Captive\",aa:bb:cc:dd:ee:ff\|
  * 10,-128,-128,-128,-128,-128,-128,-128,-128,28,28,28,28,28,-128\|0\|1'
  *
  * <p>Eg, A high quality, unmetered network with any bssid:
- * $ adb shell dumpsys activity service DefaultNetworkRecommendationService addScore \
+ * $ adb shell dumpsys activity service NetworkRecommendationService addScore \
  * '\"AnySsid\",00:00:00:00:00:00\|
  * 10,-128,-128,-128,-128,-128,-128,-128,-128,29,29,29,29,29,-128\|0\|0'
  */
@@ -85,8 +88,6 @@
 public class DefaultNetworkRecommendationProvider
         extends NetworkRecommendationProvider implements SynchronousNetworkRecommendationProvider {
     static final String TAG = "DefaultNetRecProvider";
-    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-    static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
 
     private static final String WILDCARD_MAC = "00:00:00:00:00:00";
 
@@ -132,9 +133,10 @@
     @GuardedBy("mStatsLock")
     private int mScoreCounter = 0;
 
-    public DefaultNetworkRecommendationProvider(Handler handler,
+
+    public DefaultNetworkRecommendationProvider(Context context, Executor executor,
             NetworkScoreManager scoreManager, ScoreStorage storage) {
-        super(handler);
+        super(context, executor);
         mScoreManager = scoreManager;
         mStorage = storage;
     }
@@ -159,39 +161,39 @@
         if (results != null) {
             for (int i = 0; i < results.length; i++) {
                 final ScanResult scanResult = results[i];
-                if (VERBOSE) Log.v(TAG, "Scan: " + scanResult + " " + i);
+                Blog.v(TAG, "Scan: " + scanResult + " " + i);
 
                 // We only want to recommend open networks. This check is taken from
                 // places like WifiNotificationController and will be extracted to ScanResult in
                 // a future CL.
                 if (!"[ESS]".equals(scanResult.capabilities)) {
-                    if (VERBOSE) Log.v(TAG, "Discarding closed network: " + scanResult);
+                    Blog.v(TAG, "Discarding closed network: " + scanResult);
                     continue;
                 }
 
                 final NetworkKey networkKey = new NetworkKey(
-                        new WifiKey(ScanResultUtil.createQuotedSSID(scanResult.SSID),
+                        new WifiKey(SsidUtil.quoteSsid(scanResult.SSID),
                                 scanResult.BSSID));
-                if (VERBOSE) Log.v(TAG, "Evaluating network: " + networkKey);
+                Blog.v(TAG, "Evaluating network: " + networkKey);
 
                 // We will only score networks we know about.
                 final ScoredNetwork network = mStorage.get(networkKey);
                 if (network == null) {
-                    if (VERBOSE) Log.v(TAG, "Discarding unscored network: " + scanResult);
+                    Blog.v(TAG, "Discarding unscored network: " + scanResult);
                     continue;
                 }
 
                 final int score = network.rssiCurve.lookupScore(scanResult.level);
-                if (VERBOSE) Log.d(TAG, "Scored " + scanResult + ": " + score);
+                Blog.v(TAG, "Scored " + scanResult + ": " + score);
                 if (score > recommendedScore) {
                     recommendedScanResult = scanResult;
                     recommendedScore = score;
-                    if (VERBOSE) Log.d(TAG, "New recommended network: " + scanResult);
+                    Blog.v(TAG, "New recommended network: " + scanResult);
                     continue;
                 }
             }
         } else {
-            Log.w(TAG, "Received null scan results in request.");
+            Blog.w(TAG, "Received null scan results in request.");
         }
 
         // If we ended up without a recommendation, recommend the provided configuration
@@ -208,7 +210,7 @@
         } else {
             // Build a configuration based on the scan.
             WifiConfiguration recommendedConfig = new WifiConfiguration();
-            recommendedConfig.SSID = ScanResultUtil.createQuotedSSID(recommendedScanResult.SSID);
+            recommendedConfig.SSID = SsidUtil.quoteSsid(recommendedScanResult.SSID);
             recommendedConfig.BSSID = recommendedScanResult.BSSID;
             recommendedConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
             recommendationResult = RecommendationResult
@@ -217,7 +219,7 @@
         synchronized (mStatsLock) {
             mLastRecommended = recommendationResult.getWifiConfiguration();
             mRecommendationCounter++;
-            if (DEBUG) Log.d(TAG, "Recommending network: " + configToString(mLastRecommended));
+            Blog.d(TAG, "Recommending network: " + configToString(mLastRecommended));
         }
         return recommendationResult;
     }
@@ -254,7 +256,7 @@
             return;
         }
 
-        if (DEBUG) Log.d(TAG, "Scored networks: " + scoredNetworks);
+        Blog.d(TAG, "Scored networks: " + scoredNetworks);
         safelyUpdateScores(scoredNetworks.toArray(new ScoredNetwork[scoredNetworks.size()]));
     }
 
@@ -303,7 +305,7 @@
         try {
             mScoreManager.updateScores(networkScores);
         } catch (SecurityException e) {
-            Log.w(TAG, "Tried to update scores when not the active scorer.");
+            Blog.w(TAG, "Tried to update scores when not the active scorer.");
         }
     }
 
@@ -313,7 +315,7 @@
         try {
             mScoreManager.clearScores();
         } catch (SecurityException e) {
-            Log.w(TAG, "Tried to update scores when not the active scorer.");
+            Blog.w(TAG, "Tried to update scores when not the active scorer.");
         }
     }
 
@@ -380,7 +382,7 @@
          *     score as applying to any bssid with the provided ssid.
          */
         public void addScore(ScoredNetwork scoredNetwork) {
-            if (DEBUG) Log.d(TAG, "addScore: " + scoredNetwork);
+            Blog.d(TAG, "addScore: " + scoredNetwork);
             synchronized (mScores) {
                 mScores.put(scoredNetwork.networkKey, scoredNetwork);
             }
@@ -427,5 +429,4 @@
     public ScoredNetwork getCachedScoredNetwork(NetworkKey networkKey) {
         return mStorage.get(networkKey);
     }
-
 }
diff --git a/src/com/android/networkrecommendation/DefaultNetworkRecommendationService.java b/src/com/android/networkrecommendation/DefaultNetworkRecommendationService.java
deleted file mode 100644
index 64e4f13..0000000
--- a/src/com/android/networkrecommendation/DefaultNetworkRecommendationService.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2016 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.networkrecommendation;
-
-import android.app.NotificationManager;
-import android.app.Service;
-import android.content.ContentResolver;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.net.NetworkScoreManager;
-import android.net.wifi.WifiManager;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * Provides network recommendations for the platform.
- */
-public class DefaultNetworkRecommendationService extends Service {
-
-    private HandlerThread mHandlerThread;
-    private Handler mHandler;
-    private DefaultNetworkRecommendationProvider mProvider;
-    private WifiNotificationController mWifiNotificationController;
-    private WifiWakeupController mWifiWakeupController;
-
-    @Override
-    public void onCreate() {
-        mHandlerThread = new HandlerThread("RecommendationProvider");
-        mHandlerThread.start();
-        Looper looper = mHandlerThread.getLooper();
-        mHandler = new Handler(looper);
-        NetworkScoreManager networkScoreManager = getSystemService(NetworkScoreManager.class);
-        mProvider = new DefaultNetworkRecommendationProvider(mHandler,
-                networkScoreManager, new DefaultNetworkRecommendationProvider.ScoreStorage());
-        NotificationManager notificationManager = getSystemService(NotificationManager.class);
-        WifiManager wifiManager = getSystemService(WifiManager.class);
-        Resources resources = getResources();
-        ContentResolver contentResolver = getContentResolver();
-        mWifiNotificationController = new WifiNotificationController(
-                this, contentResolver, new Handler(looper), mProvider,
-                wifiManager, notificationManager,
-                new WifiNotificationHelper(this, mProvider));
-        WifiWakeupNetworkSelector wifiWakeupNetworkSelector =
-                new WifiWakeupNetworkSelector(resources);
-        WifiWakeupNotificationHelper wifiWakeupNotificationHelper =
-                new WifiWakeupNotificationHelper(this, resources, new Handler(looper),
-                        notificationManager, wifiManager);
-        mWifiWakeupController = new WifiWakeupController(this, contentResolver, looper,
-                wifiManager, wifiWakeupNetworkSelector, wifiWakeupNotificationHelper);
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        mWifiWakeupController.start();
-        mWifiNotificationController.start();
-        return mProvider.getBinder();
-    }
-
-    @Override
-    public boolean onUnbind(Intent intent) {
-        mWifiWakeupController.stop();
-        mWifiNotificationController.stop();
-        return super.onUnbind(intent);
-    }
-
-    @Override
-    protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
-        mProvider.dump(fd, writer, args);
-        mWifiNotificationController.dump(fd, writer, args);
-        mWifiWakeupController.dump(fd, writer, args);
-    }
-}
diff --git a/src/com/android/networkrecommendation/Example.java b/src/com/android/networkrecommendation/Example.java
new file mode 100644
index 0000000..a85a112
--- /dev/null
+++ b/src/com/android/networkrecommendation/Example.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017 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.networkrecommendation;
+
+import android.net.RecommendationRequest;
+
+import java.lang.reflect.Method;
+
+public class Example {
+
+    public Example() {}
+
+    public void buildRecommendationRequest() {
+        new RecommendationRequest.Builder().build();
+    }
+
+    @SuppressWarnings("unchecked")
+    public RecommendationRequest reflectRecommendationRequest() {
+        try {
+            Class builder = RecommendationRequest.class.getClasses()[0];
+            Object builderObj = builder.getConstructor().newInstance();
+            Method build = builder.getDeclaredMethod("build");
+            return (RecommendationRequest) build.invoke(builderObj);
+        } catch (Exception e) {
+            throw new RuntimeException("Noooo", e);
+        }
+    }
+}
diff --git a/src/com/android/networkrecommendation/ImageUtils.java b/src/com/android/networkrecommendation/ImageUtils.java
deleted file mode 100644
index 4b3d042..0000000
--- a/src/com/android/networkrecommendation/ImageUtils.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2017 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.networkrecommendation;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-
-/** Helper for image manipulation */
-public class ImageUtils {
-
-    /**
-     * Convert a drawable to a bitmap, scaled to fit within maxWidth and maxHeight.
-     */
-    public static Bitmap buildScaledBitmap(Drawable drawable, int maxWidth,
-            int maxHeight) {
-        if (drawable == null) {
-            return null;
-        }
-        int originalWidth = drawable.getIntrinsicWidth();
-        int originalHeight = drawable.getIntrinsicHeight();
-
-        if ((originalWidth <= maxWidth) && (originalHeight <= maxHeight)
-                && (drawable instanceof BitmapDrawable)) {
-            return ((BitmapDrawable) drawable).getBitmap();
-        }
-        if (originalHeight <= 0 || originalWidth <= 0) {
-            return null;
-        }
-
-        // create a new bitmap, scaling down to fit the max dimensions of
-        // a large notification icon if necessary
-        float ratio = Math.min((float) maxWidth / (float) originalWidth,
-                (float) maxHeight / (float) originalHeight);
-        ratio = Math.min(1.0f, ratio);
-        int scaledWidth = (int) (ratio * originalWidth);
-        int scaledHeight = (int) (ratio * originalHeight);
-        Bitmap result = Bitmap.createBitmap(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888);
-
-        // and paint our app bitmap on it
-        Canvas canvas = new Canvas(result);
-        drawable.setBounds(0, 0, scaledWidth, scaledHeight);
-        drawable.draw(canvas);
-
-        return result;
-    }
-}
diff --git a/src/com/android/networkrecommendation/NetworkRecommendationApp.java b/src/com/android/networkrecommendation/NetworkRecommendationApp.java
new file mode 100644
index 0000000..c63c875
--- /dev/null
+++ b/src/com/android/networkrecommendation/NetworkRecommendationApp.java
@@ -0,0 +1,17 @@
+package com.android.networkrecommendation;
+
+import android.app.Application;
+
+import com.android.networkrecommendation.config.PreferenceFile;
+
+/**
+ * Initialize app-wide state.
+ */
+public class NetworkRecommendationApp extends Application {
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        PreferenceFile.init(this);
+    }
+}
diff --git a/src/com/android/networkrecommendation/NetworkRecommendationService.java b/src/com/android/networkrecommendation/NetworkRecommendationService.java
new file mode 100644
index 0000000..d4923d0
--- /dev/null
+++ b/src/com/android/networkrecommendation/NetworkRecommendationService.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2016 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.networkrecommendation;
+
+import android.app.NotificationManager;
+import android.app.Service;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.net.NetworkScoreManager;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.PowerManager;
+import android.os.UserManager;
+
+import com.android.networkrecommendation.notify.WifiNotificationController;
+import com.android.networkrecommendation.notify.WifiNotificationHelper;
+import com.android.networkrecommendation.util.NotificationChannelUtil;
+import com.android.networkrecommendation.wakeup.WifiWakeupController;
+import com.android.networkrecommendation.wakeup.WifiWakeupHelper;
+import com.android.networkrecommendation.wakeup.WifiWakeupNetworkSelector;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * Provides network recommendations for the platform.
+ */
+public class NetworkRecommendationService extends Service {
+
+    private HandlerThread mProviderHandlerThread;
+    private Handler mProviderHandler;
+    private HandlerThread mControllerHandlerThread;
+    private Handler mControllerHandler;
+    private DefaultNetworkRecommendationProvider mProvider;
+    private WifiNotificationController mWifiNotificationController;
+    private WifiWakeupController mWifiWakeupController;
+
+    @Override
+    public void onCreate() {
+        mProviderHandlerThread = new HandlerThread("RecommendationProvider");
+        mProviderHandlerThread.start();
+        mProviderHandler = new Handler(mProviderHandlerThread.getLooper());
+        NetworkScoreManager networkScoreManager = getSystemService(NetworkScoreManager.class);
+        mProvider = new DefaultNetworkRecommendationProvider(this, mProviderHandler::post,
+                networkScoreManager, new DefaultNetworkRecommendationProvider.ScoreStorage());
+
+        mControllerHandlerThread = new HandlerThread("RecommendationProvider");
+        mControllerHandlerThread.start();
+        mControllerHandler = new Handler(mControllerHandlerThread.getLooper());
+        NotificationManager notificationManager = getSystemService(NotificationManager.class);
+        NotificationChannelUtil.configureNotificationChannels(notificationManager, this);
+
+        WifiManager wifiManager = getSystemService(WifiManager.class);
+        PowerManager powerManager = getSystemService(PowerManager.class);
+        UserManager userManager = getSystemService(UserManager.class);
+        Resources resources = getResources();
+        ContentResolver contentResolver = getContentResolver();
+        mWifiNotificationController = new WifiNotificationController(
+                this, contentResolver, mControllerHandler, mProvider,
+                wifiManager, notificationManager, userManager, new WifiNotificationHelper(this));
+        WifiWakeupNetworkSelector wifiWakeupNetworkSelector =
+                new WifiWakeupNetworkSelector(resources, mProvider);
+        WifiWakeupHelper wifiWakeupHelper = new WifiWakeupHelper(this, resources, mControllerHandler,
+                notificationManager, wifiManager);
+        mWifiWakeupController =
+                new WifiWakeupController(this, getContentResolver(), mControllerHandler, wifiManager,
+                        powerManager, userManager, wifiWakeupNetworkSelector, wifiWakeupHelper);
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        mWifiWakeupController.start();
+        mWifiNotificationController.start();
+        return mProvider.getBinder();
+    }
+
+    @Override
+    public boolean onUnbind(Intent intent) {
+        mWifiWakeupController.stop();
+        mWifiNotificationController.stop();
+        return super.onUnbind(intent);
+    }
+
+    @Override
+    public void onDestroy() {
+        mProviderHandlerThread.quit();
+        super.onDestroy();
+    }
+
+    @Override
+    protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+        mProvider.dump(fd, writer, args);
+        mWifiNotificationController.dump(fd, writer, args);
+        mWifiWakeupController.dump(fd, writer, args);
+    }
+}
diff --git a/src/com/android/networkrecommendation/SynchronousNetworkRecommendationProvider.java b/src/com/android/networkrecommendation/SynchronousNetworkRecommendationProvider.java
index 44a7e0d..b2ff12c 100644
--- a/src/com/android/networkrecommendation/SynchronousNetworkRecommendationProvider.java
+++ b/src/com/android/networkrecommendation/SynchronousNetworkRecommendationProvider.java
@@ -24,7 +24,7 @@
 /**
  * Provider to return {@link ScoredNetwork} from cached scores in NetworkRecommendationProvider.
  */
-interface SynchronousNetworkRecommendationProvider {
+public interface SynchronousNetworkRecommendationProvider {
 
     /** Returns a {@link ScoredNetwork} if present in the cache. Otherwise, return null. */
     ScoredNetwork getCachedScoredNetwork(NetworkKey networkKey);
diff --git a/src/com/android/networkrecommendation/WifiNotificationController.java b/src/com/android/networkrecommendation/WifiNotificationController.java
deleted file mode 100644
index 9dbb665..0000000
--- a/src/com/android/networkrecommendation/WifiNotificationController.java
+++ /dev/null
@@ -1,456 +0,0 @@
-/*
- * Copyright (C) 2017 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.networkrecommendation;
-
-import android.app.Notification;
-import android.app.NotificationManager;
-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.graphics.Bitmap;
-import android.net.NetworkInfo;
-import android.net.NetworkScoreManager;
-import android.net.RecommendationRequest;
-import android.net.RecommendationResult;
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiManager;
-import android.os.Handler;
-import android.provider.Settings;
-import android.support.annotation.Nullable;
-import android.support.annotation.VisibleForTesting;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * Takes care of handling the "open wi-fi network available" notification
- * @hide
- */
-public class WifiNotificationController {
-    /**
-     * The icon to show in the 'available networks' notification. This will also
-     * be the ID of the Notification given to the NotificationManager.
-     */
-    private static final int ICON_NETWORKS_AVAILABLE = R.drawable.stat_notify_wifi_in_range;
-    /**
-     * When a notification is shown, we wait this amount before possibly showing it again.
-     */
-    private final long mNotificationRepeatDelayMs;
-    /**
-     * Whether the user has set the setting to show the 'available networks' notification.
-     */
-    private boolean mNotificationEnabled;
-    /**
-     * Observes the user setting to keep {@link #mNotificationEnabled} in sync.
-     */
-    private final NotificationEnabledSettingObserver mNotificationEnabledSettingObserver;
-    /**
-     * The {@link System#currentTimeMillis()} must be at least this value for us
-     * to show the notification again.
-     */
-    private long mNotificationRepeatTime;
-    /**
-     * Whether the notification is being shown.
-     */
-    private boolean mNotificationShown;
-    /**
-     * The number of continuous scans that must occur before consider the
-     * supplicant in a scanning state. This allows supplicant to associate with
-     * remembered networks that are in the scan results.
-     */
-    private static final int NUM_SCANS_BEFORE_ACTUALLY_SCANNING = 3;
-    /**
-     * The number of scans since the last network state change. When this
-     * exceeds {@link #NUM_SCANS_BEFORE_ACTUALLY_SCANNING}, we consider the
-     * supplicant to actually be scanning. When the network state changes to
-     * something other than scanning, we reset this to 0.
-     */
-    private int mNumScansSinceNetworkStateChange;
-    /**
-     * Time in milliseconds to display the Connecting notification.
-     */
-    private static final int TIME_TO_SHOW_CONNECTING_MILLIS = 10000;
-    /**
-     * Time in milliseconds to display the Connected notification.
-     */
-    private static final int TIME_TO_SHOW_CONNECTED_MILLIS = 5000;
-    /**
-     * Time in milliseconds to display the Failed To Connect notification.
-     */
-    private static final int TIME_TO_SHOW_FAILED_MILLIS = 5000;
-    /**
-     * Try to connect to provided WifiConfiguration since user wants to
-     * connect to the recommended open access point.
-     */
-    static final String ACTION_CONNECT_TO_RECOMMENDED_NETWORK =
-            "com.android.networkrecommendation.CONNECT_TO_RECOMMENDED_NETWORK";
-    /**
-     * Handles behavior when notification is deleted.
-     */
-    static final String ACTION_NOTIFICATION_DELETED =
-            "com.android.networkrecommendation.NOTIFICATION_DELETED";
-    /**
-     * Network recommended by {@link NetworkScoreManager#requestRecommendation}.
-     */
-    private WifiConfiguration mRecommendedNetwork;
-    private Bitmap mNotificationBadgeBitmap;
-    /**
-     * Whether {@link WifiNotificationController} has been started.
-     */
-    private final AtomicBoolean mStarted;
-    /**
-     * Runnable to dismiss notification.
-     */
-    @VisibleForTesting
-    final Runnable mDismissNotificationRunnable = () -> {
-        removeNotification();
-    };
-    /**
-     * Runnable to show Failed To Connect notification.
-     */
-    @VisibleForTesting
-    final Runnable mShowFailedToConnectNotificationRunnable = () -> {
-        showFailedToConnectNotification();
-    };
-
-    private static final String TAG = "WifiNotification";
-
-    private final Context mContext;
-    private final Handler mHandler;
-    private final ContentResolver mContentResolver;
-    private final SynchronousNetworkRecommendationProvider mNetworkRecommendationProvider;
-    private final WifiManager mWifiManager;
-    private final NotificationManager mNotificationManager;
-    private final WifiNotificationHelper mWifiNotificationHelper;
-    private NetworkInfo mNetworkInfo;
-    private NetworkInfo.DetailedState mDetailedState;
-    private volatile int mWifiState;
-
-    WifiNotificationController(Context context, ContentResolver contentResolver, Handler handler,
-            SynchronousNetworkRecommendationProvider networkRecommendationProvider,
-            WifiManager wifiManager, NotificationManager notificationManager,
-            WifiNotificationHelper helper) {
-        mContext = context;
-        mContentResolver = contentResolver;
-        mNetworkRecommendationProvider = networkRecommendationProvider;
-        mWifiManager = wifiManager;
-        mNotificationManager = notificationManager;
-        mHandler = handler;
-        mWifiNotificationHelper = helper;
-        mStarted = new AtomicBoolean(false);
-
-        // Setting is in seconds
-        mNotificationRepeatDelayMs = Settings.Global.getInt(
-                contentResolver, Settings.Global.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY, 900) * 1000L;
-        mNotificationEnabledSettingObserver = new NotificationEnabledSettingObserver(mHandler);
-    }
-
-    /** Starts {@link WifiNotificationController}. */
-    public void start() {
-        if (!mStarted.compareAndSet(false, true)) {
-            return;
-        }
-
-        mWifiState = WifiManager.WIFI_STATE_UNKNOWN;
-        mDetailedState = NetworkInfo.DetailedState.IDLE;
-
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
-        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
-        filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
-        filter.addAction(ACTION_CONNECT_TO_RECOMMENDED_NETWORK);
-        filter.addAction(ACTION_NOTIFICATION_DELETED);
-
-        mContext.registerReceiver(
-                mBroadcastReceiver, filter, null /* broadcastPermission */, mHandler);
-        mNotificationEnabledSettingObserver.register();
-    }
-
-    /** Stops {@link WifiNotificationController}. */
-    public void stop() {
-        if (!mStarted.compareAndSet(true, false)) {
-            return;
-        }
-        mContext.unregisterReceiver(mBroadcastReceiver);
-        mNotificationEnabledSettingObserver.register();
-    }
-
-    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
-                mWifiState = mWifiManager.getWifiState();
-                resetNotification();
-            } else if (intent.getAction().equals(
-                    WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
-                mNetworkInfo = (NetworkInfo) intent.getParcelableExtra(
-                        WifiManager.EXTRA_NETWORK_INFO);
-                NetworkInfo.DetailedState detailedState =
-                        mNetworkInfo.getDetailedState();
-                if (detailedState != NetworkInfo.DetailedState.SCANNING
-                        && detailedState != mDetailedState) {
-                    mDetailedState = detailedState;
-                    switch (mDetailedState) {
-                        case CONNECTED:
-                            updateNotificationOnConnect();
-                            break;
-                        case DISCONNECTED:
-                        case CAPTIVE_PORTAL_CHECK:
-                            resetNotification();
-                            break;
-
-                        // TODO: figure out if these are failure cases when connecting
-                        case IDLE:
-                        case SCANNING:
-                        case CONNECTING:
-                        case AUTHENTICATING:
-                        case OBTAINING_IPADDR:
-                        case SUSPENDED:
-                        case FAILED:
-                        case BLOCKED:
-                        case VERIFYING_POOR_LINK:
-                            break;
-                    }
-                }
-            } else if (intent.getAction().equals(
-                    WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
-                checkAndSetNotification(mNetworkInfo, mWifiManager.getScanResults());
-            } else if (intent.getAction().equals(ACTION_CONNECT_TO_RECOMMENDED_NETWORK)) {
-                connectToRecommendedNetwork();
-            } else if (intent.getAction().equals(ACTION_NOTIFICATION_DELETED)) {
-                handleNotificationDeleted();
-            }
-        }
-    };
-
-    private void checkAndSetNotification(NetworkInfo networkInfo,
-            List<ScanResult> scanResults) {
-
-        // TODO: unregister broadcast so we do not have to check here
-        // If we shouldn't place a notification on available networks, then
-        // don't bother doing any of the following
-        if (!mNotificationEnabled) return;
-        if (mWifiState != WifiManager.WIFI_STATE_ENABLED) return;
-        if (scanResults == null || scanResults.isEmpty()) return;
-
-        NetworkInfo.State state = NetworkInfo.State.DISCONNECTED;
-        if (networkInfo != null) {
-            state = networkInfo.getState();
-        }
-
-
-        if (state == NetworkInfo.State.DISCONNECTED
-                || state == NetworkInfo.State.UNKNOWN) {
-            RecommendationResult result = getOpenNetworkRecommendation(scanResults);
-            if (result != null
-                    && result.getWifiConfiguration() != null) {
-                mRecommendedNetwork = result.getWifiConfiguration();
-                mNotificationBadgeBitmap = mWifiNotificationHelper.createNotificationBadgeBitmap(
-                        mRecommendedNetwork, scanResults);
-                if (++mNumScansSinceNetworkStateChange >= NUM_SCANS_BEFORE_ACTUALLY_SCANNING
-                        && mNotificationBadgeBitmap != null) {
-                    /*
-                     * We have scanned continuously at least
-                     * NUM_SCANS_BEFORE_NOTIFICATION times. The user
-                     * probably does not have a remembered network in range,
-                     * since otherwise supplicant would have tried to
-                     * associate and thus resetting this counter.
-                     */
-                    displayNotification();
-                }
-                return;
-            }
-        }
-
-        // No open networks in range, remove the notification
-        removeNotification();
-    }
-
-    /**
-     * Uses {@link NetworkScoreManager} to choose a qualified network out of the list of
-     * {@link ScanResult}s.
-     *
-     * @return returns the best qualified open networks, if any.
-     */
-    @Nullable
-    private RecommendationResult getOpenNetworkRecommendation(List<ScanResult> scanResults) {
-        if (scanResults == null || scanResults.isEmpty()) {
-            return null;
-        }
-        ArrayList<ScanResult> openNetworks = new ArrayList<>();
-        for (ScanResult scanResult : scanResults) {
-            //A capability of [ESS] represents an open access point
-            //that is available for an STA to connect
-            if ("[ESS]".equals(scanResult.capabilities)) {
-                openNetworks.add(scanResult);
-            }
-        }
-        RecommendationRequest request = new RecommendationRequest.Builder()
-                .setScanResults(openNetworks.toArray(new ScanResult[openNetworks.size()]))
-                .build();
-
-        return mNetworkRecommendationProvider.requestRecommendation(request);
-    }
-
-    /**
-     * Display's a notification that there are open Wi-Fi networks.
-     */
-    private void displayNotification() {
-
-        // Since we use auto cancel on the notification, when the
-        // mNetworksAvailableNotificationShown is true, the notification may
-        // have actually been canceled.  However, when it is false we know
-        // for sure that it is not being shown (it will not be shown any other
-        // place than here)
-
-        // Not enough time has passed to show the notification again
-
-        if (System.currentTimeMillis() < mNotificationRepeatTime) {
-            return;
-        }
-        Notification notification = mWifiNotificationHelper.createMainNotification(
-                        mRecommendedNetwork, mNotificationBadgeBitmap);
-        mNotificationRepeatTime = System.currentTimeMillis() + mNotificationRepeatDelayMs;
-
-        postNotification(notification);
-        mNotificationShown = true;
-    }
-
-
-    /**
-     * Attempts to connect to recommended network and updates the notification to
-     * show Connecting state.
-     * TODO(33668991): work with UX to polish notification UI and figure out failure states
-     */
-    private void connectToRecommendedNetwork() {
-        if (mRecommendedNetwork == null) {
-            return;
-        }
-        // Attempts to connect to recommended network.
-        mWifiManager.connect(mRecommendedNetwork, null /* actionListener */);
-
-        // Update notification to connecting status.
-        Notification notification = mWifiNotificationHelper.createConnectingNotification(
-                        mRecommendedNetwork, mNotificationBadgeBitmap);
-        postNotification(notification);
-        mHandler.postDelayed(mShowFailedToConnectNotificationRunnable,
-                TIME_TO_SHOW_CONNECTING_MILLIS);
-    }
-
-    /**
-     * When detailed state changes to CONNECTED, show connected notification or
-     * reset notification.
-     * TODO: determine failure state where main notification shows but connected.
-     */
-    private void updateNotificationOnConnect() {
-        if (!mNotificationShown) {
-            return;
-        }
-
-        Notification notification = mWifiNotificationHelper.createConnectedNotification(
-                mRecommendedNetwork, mNotificationBadgeBitmap);
-        postNotification(notification);
-        // Remove any previous reset notification callbacks.
-        mHandler.removeCallbacks(mShowFailedToConnectNotificationRunnable);
-        mHandler.postDelayed(mDismissNotificationRunnable, TIME_TO_SHOW_CONNECTED_MILLIS);
-    }
-
-    /**
-     * Displays the Failed To Connect notification after the Connecting notification
-     * is shown for {@link #TIME_TO_SHOW_CONNECTING_MILLIS} duration.
-     */
-    private void showFailedToConnectNotification() {
-        Notification notification =
-                mWifiNotificationHelper.createFailedToConnectNotification(mRecommendedNetwork);
-        postNotification(notification);
-        mHandler.postDelayed(mDismissNotificationRunnable, TIME_TO_SHOW_FAILED_MILLIS);
-    }
-
-    /**
-     * Handles behavior when notification is dismissed.
-     */
-    private void handleNotificationDeleted() {
-        mNotificationShown = false;
-        mRecommendedNetwork = null;
-        mNotificationBadgeBitmap = null;
-    }
-
-    private void postNotification(Notification notification) {
-        mNotificationManager.notify(null /* tag */, ICON_NETWORKS_AVAILABLE, notification);
-    }
-
-    /**
-     * Clears variables related to tracking whether a notification has been
-     * shown recently and clears the current notification.
-     */
-    private void resetNotification() {
-        mNotificationRepeatTime = 0;
-        mNumScansSinceNetworkStateChange = 0;
-        if (mNotificationShown) {
-            removeNotification();
-        }
-    }
-
-    private void removeNotification() {
-        mNotificationManager.cancel(null /* tag */, ICON_NETWORKS_AVAILABLE);
-        mNotificationShown = false;
-    }
-
-    void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("mNotificationEnabled " + mNotificationEnabled);
-        pw.println("mNotificationRepeatTime " + mNotificationRepeatTime);
-        pw.println("mNotificationShown " + mNotificationShown);
-        pw.println("mNumScansSinceNetworkStateChange " + mNumScansSinceNetworkStateChange);
-    }
-
-    private class NotificationEnabledSettingObserver extends ContentObserver {
-        NotificationEnabledSettingObserver(Handler handler) {
-            super(handler);
-        }
-
-        public void register() {
-            mContentResolver.registerContentObserver(Settings.Global.getUriFor(
-                    Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON), true, this);
-            mNotificationEnabled = getValue();
-        }
-
-        public void unregister() {
-            mContentResolver.unregisterContentObserver(this);
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            super.onChange(selfChange);
-
-            mNotificationEnabled = getValue();
-            resetNotification();
-        }
-
-        private boolean getValue() {
-            return Settings.Global.getInt(
-                    mContentResolver,
-                    Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 0) == 1;
-        }
-    }
-}
diff --git a/src/com/android/networkrecommendation/WifiNotificationHelper.java b/src/com/android/networkrecommendation/WifiNotificationHelper.java
deleted file mode 100644
index e4c8c4e..0000000
--- a/src/com/android/networkrecommendation/WifiNotificationHelper.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2017 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.networkrecommendation;
-
-import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
-
-import android.app.Notification;
-import android.app.Notification.Action;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.LayerDrawable;
-import android.net.NetworkKey;
-import android.net.ScoredNetwork;
-import android.net.WifiKey;
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiManager;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.text.Spannable;
-import android.text.SpannableString;
-import android.text.style.ForegroundColorSpan;
-
-import java.util.List;
-
-/**
- * Helper class that creates notifications for {@link WifiNotificationController}.
- */
-public class WifiNotificationHelper {
-    private final Context mContext;
-    private final SynchronousNetworkRecommendationProvider mCachedScoredNetworkProvider;
-
-    public WifiNotificationHelper(
-            Context context, SynchronousNetworkRecommendationProvider cachedScoredNetworkProvider) {
-        mContext = context;
-        mCachedScoredNetworkProvider = cachedScoredNetworkProvider;
-    }
-
-    /**
-     * Creates the main open networks notification with two actions. "Options" link to the
-     * Wi-Fi picker activity, and "Connect" prompts {@link WifiNotificationController}
-     * to connect to the recommended network.
-     */
-    public Notification createMainNotification(WifiConfiguration config, Bitmap badge) {
-        PendingIntent optionsIntent = PendingIntent.getActivity(
-                mContext, 0, new Intent(WifiManager.ACTION_PICK_WIFI_NETWORK), FLAG_UPDATE_CURRENT);
-        Action optionsAction = new Action.Builder(
-                null /* icon */,
-                mContext.getText(R.string.wifi_available_options),
-                optionsIntent)
-                .build();
-        PendingIntent connectIntent = PendingIntent.getBroadcast(
-                mContext,
-                0,
-                new Intent(WifiNotificationController.ACTION_CONNECT_TO_RECOMMENDED_NETWORK),
-                FLAG_UPDATE_CURRENT);
-        Action connectAction = new Action.Builder(
-                null /* icon */,
-                mContext.getText(R.string.wifi_available_connect),
-                connectIntent)
-                .build();
-        return createNotificationBuilder(config, badge)
-                .addAction(connectAction)
-                .addAction(optionsAction)
-                .build();
-    }
-
-    /**
-     * Creates the notification that indicates the controller is attempting to connect
-     * to the recommended network.
-     */
-    public Notification createConnectingNotification(WifiConfiguration config, Bitmap badge) {
-        Action connecting = new Action.Builder(
-                null /* icon */,
-                mContext.getText(R.string.wifi_available_connecting),
-                null /* pendingIntent */)
-                .build();
-        return createNotificationBuilder(config, badge)
-                .addAction(connecting)
-                .setProgress(0 /* max */, 0 /* progress */, true /* indeterminate */)
-                .build();
-    }
-
-    /**
-     * Creates the notification that indicates the controller successfully connected
-     * to the recommended network.
-     */
-    public Notification createConnectedNotification(WifiConfiguration config, Bitmap badge) {
-        Action connected = new Action.Builder(
-                null /* icon */,
-                mContext.getText(R.string.wifi_available_connected),
-                null /* pendingIntent */)
-                .build();
-        return createNotificationBuilder(config, badge)
-                .addAction(connected)
-                .build();
-    }
-
-    /**
-     * Creates the notification that indicates the controller failed to connect to
-     * the recommended network.
-     */
-    public Notification createFailedToConnectNotification(WifiConfiguration config) {
-        Spannable failedText =
-                new SpannableString(mContext.getText(R.string.wifi_available_failed));
-        Resources resources = mContext.getResources();
-        Drawable iconDrawable = mContext.getDrawable(R.drawable.ic_signal_wifi_no_network);
-        iconDrawable.setTint(mContext.getColor(R.color.color_tint));
-        Bitmap icon = ImageUtils.buildScaledBitmap(
-                iconDrawable,
-                resources.getDimensionPixelSize(android.R.dimen.notification_large_icon_width),
-                resources.getDimensionPixelSize(android.R.dimen.notification_large_icon_height));
-        failedText.setSpan(new ForegroundColorSpan(
-                Color.RED), 0, failedText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
-        return createNotificationBuilder(config, icon)
-                .setContentText(failedText)
-                .build();
-    }
-
-    private Notification.Builder createNotificationBuilder(WifiConfiguration config, Bitmap badge) {
-        CharSequence title = mContext.getText(R.string.wifi_available);
-        PendingIntent deleteIntent = PendingIntent.getBroadcast(
-                mContext,
-                0,
-                new Intent(WifiNotificationController.ACTION_NOTIFICATION_DELETED),
-                FLAG_UPDATE_CURRENT);
-        return new Notification.Builder(mContext)
-                .setDeleteIntent(deleteIntent)
-                .setSmallIcon(R.drawable.stat_notify_wifi_in_range)
-                .setLargeIcon(badge)
-                .setAutoCancel(true)
-                .setTicker(title)
-                .setContentTitle(title)
-                .setContentText(WifiConfigurationUtil.getPrintableSsid(config))
-                .addExtras(getSystemLabelExtras());
-    }
-
-    private Bundle getSystemLabelExtras() {
-        Bundle extras = new Bundle();
-        extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
-                mContext.getString(R.string.android_system_label));
-        return extras;
-    }
-
-    //TODO(34177812): Share this logic between systemUi and Settings.
-    static final int[] WIFI_PIE_FOR_BADGING = {
-            R.drawable.ic_signal_wifi_badged_0_bars,
-            R.drawable.ic_signal_wifi_badged_1_bar,
-            R.drawable.ic_signal_wifi_badged_2_bars,
-            R.drawable.ic_signal_wifi_badged_3_bars,
-            R.drawable.ic_signal_wifi_badged_4_bars
-    };
-
-    private int getWifiBadgeResourceForEnum(int badgeEnum) {
-        switch (badgeEnum) {
-            case ScoredNetwork.BADGING_NONE:
-                return 0;
-            case ScoredNetwork.BADGING_SD:
-                return R.drawable.ic_signal_wifi_badged_sd;
-            case ScoredNetwork.BADGING_HD:
-                return R.drawable.ic_signal_wifi_badged_hd;
-            case ScoredNetwork.BADGING_4K:
-                return R.drawable.ic_signal_wifi_badged_4k;
-            default:
-                throw new IllegalArgumentException("No badge resource for enum :" + badgeEnum);
-        }
-    }
-
-    /**
-     * Creates a Wi-Fi badge for the notification using matching {@link ScanResult}'s RSSI
-     * and badging from {@link CachedScoredNetworkProvider}.
-     */
-    public Bitmap createNotificationBadgeBitmap(
-            @NonNull WifiConfiguration config,
-            @NonNull List<ScanResult> scanResults) {
-        ScanResult matchingScanResult = findMatchingScanResult(scanResults, config);
-        if (matchingScanResult == null) {
-            return null;
-        }
-        int rssi = matchingScanResult.level;
-        WifiKey wifiKey = new WifiKey(config.SSID, config.BSSID);
-        ScoredNetwork scoredNetwork =
-                mCachedScoredNetworkProvider.getCachedScoredNetwork(new NetworkKey(wifiKey));
-        if (scoredNetwork != null) {
-            return getBadgedWifiBitmap(scoredNetwork.calculateBadge(rssi), rssi);
-        }
-        return null;
-    }
-
-    private Bitmap getBadgedWifiBitmap(int badgeEnum, int rssi) {
-        if (badgeEnum == ScoredNetwork.BADGING_NONE) {
-            return null;
-        }
-        int signalLevel = WifiManager.calculateSignalLevel(rssi, 5);
-        LayerDrawable layerDrawable = new LayerDrawable(new Drawable[]{
-                mContext.getDrawable(WIFI_PIE_FOR_BADGING[signalLevel]),
-                mContext.getDrawable(getWifiBadgeResourceForEnum(badgeEnum))});
-        layerDrawable.setTint(mContext.getColor(R.color.color_tint));
-        Resources resources = mContext.getResources();
-        return ImageUtils.buildScaledBitmap(layerDrawable,
-                resources.getDimensionPixelSize(android.R.dimen.notification_large_icon_width),
-                resources.getDimensionPixelSize(android.R.dimen.notification_large_icon_height));
-    }
-
-    private ScanResult findMatchingScanResult(List<ScanResult> scanResults,
-            WifiConfiguration wifiConfiguration) {
-        String ssid = WifiConfigurationUtil.removeDoubleQuotes(wifiConfiguration);
-        String bssid = wifiConfiguration.BSSID;
-        for (ScanResult scanResult : scanResults) {
-            if (ssid.equals(scanResult.SSID) && bssid.equals(scanResult.BSSID)) {
-                return scanResult;
-            }
-        }
-        return null;
-    }
-}
diff --git a/src/com/android/networkrecommendation/WifiWakeupController.java b/src/com/android/networkrecommendation/WifiWakeupController.java
deleted file mode 100644
index 5fe65ef..0000000
--- a/src/com/android/networkrecommendation/WifiWakeupController.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (C) 2017 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.networkrecommendation;
-
-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.wifi.ScanResult;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiManager;
-import android.os.Handler;
-import android.os.Looper;
-import android.provider.Settings;
-import android.support.annotation.VisibleForTesting;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * Handles enabling Wi-Fi for the Wi-Fi Wakeup feature.
- *
- * <p>
- * This class enables Wi-Fi when the user is near a network that would would autojoined if Wi-Fi
- * were enabled. When a user disables Wi-Fi, Wi-Fi Wakeup will not enable Wi-Fi until the
- * user's context has changed. For saved networks, this context change is defined by the user
- * leaving the range of the saved SSIDs that were in range when the user disabled Wi-Fi.
- *
- * @hide
- */
-public class WifiWakeupController {
-    private static final String TAG = "WifiWakeupController";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
-
-    /** Number of scans to ensure that a previously in range AP is now out of range. */
-    private static final int NUM_SCANS_TO_CONFIRM_AP_LOSS = 3;
-
-    private final Context mContext;
-    private final ContentResolver mContentResolver;
-    private final WifiManager mWifiManager;
-    private final WifiWakeupNetworkSelector mWifiWakeupNetworkSelector;
-    private final Handler mHandler;
-    private final WifiWakeupNotificationHelper mWifiWakeupNotificationHelper;
-    private final AtomicBoolean mStarted;
-    @VisibleForTesting final ContentObserver mContentObserver;
-
-    private final Map<String, WifiConfiguration> mSavedNetworks = new ArrayMap<>();
-    private final Set<String> mSavedSsidsInLastScan = new ArraySet<>();
-    private final Set<String> mSavedSsids = new ArraySet<>();
-    private final Map<String, Integer> mSavedSsidsOnDisable = new ArrayMap<>();
-    private int mWifiState;
-    private int mWifiApState;
-    private boolean mWifiWakeupEnabled;
-    private boolean mAirplaneModeEnabled;
-
-    WifiWakeupController(Context context, ContentResolver contentResolver, Looper looper,
-            WifiManager wifiManager, WifiWakeupNetworkSelector wifiWakeupNetworkSelector,
-            WifiWakeupNotificationHelper wifiWakeupNotificationHelper) {
-        mContext = context;
-        mContentResolver = contentResolver;
-        mHandler = new Handler(looper);
-        mWifiWakeupNotificationHelper = wifiWakeupNotificationHelper;
-        mStarted = new AtomicBoolean(false);
-        mWifiManager = wifiManager;
-        mWifiWakeupNetworkSelector = wifiWakeupNetworkSelector;
-        mContentObserver = new ContentObserver(mHandler) {
-            @Override
-            public void onChange(boolean selfChange) {
-                mWifiWakeupEnabled = Settings.Global.getInt(mContentResolver,
-                        Settings.Global.WIFI_WAKEUP_ENABLED, 0) == 1;
-                mAirplaneModeEnabled = Settings.Global.getInt(mContentResolver,
-                        Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
-            }
-        };
-    }
-
-    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (!mWifiWakeupEnabled) {
-                return;
-            }
-
-            if (WifiManager.WIFI_AP_STATE_CHANGED_ACTION.equals(intent.getAction())) {
-                handleWifiApStateChanged();
-            } else if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) {
-                handleWifiStateChanged();
-            } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(intent.getAction())) {
-                handleScanResultsAvailable();
-            } else if (WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION.equals(intent.getAction())) {
-                handleConfiguredNetworksChanged();
-            }
-        }
-    };
-
-    /** Starts {@link WifiWakeupController}. */
-    public void start() {
-        if (!mStarted.compareAndSet(false, true)) {
-            return;
-        }
-        if (DEBUG) {
-            Log.d(TAG, "Starting WifiWakeupController.");
-        }
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
-        filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
-        filter.addAction(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION);
-        filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
-        // TODO(b/33695273): conditionally register this receiver based on wifi enabled setting
-        mContext.registerReceiver(mBroadcastReceiver, filter, null, mHandler);
-        mContentResolver.registerContentObserver(Settings.Global.getUriFor(
-                Settings.Global.WIFI_WAKEUP_ENABLED), true, mContentObserver);
-        mContentResolver.registerContentObserver(Settings.Global.getUriFor(
-                Settings.Global.AIRPLANE_MODE_ON), true, mContentObserver);
-        mContentObserver.onChange(true);
-        handleWifiStateChanged();
-        handleWifiApStateChanged();
-        handleConfiguredNetworksChanged();
-        handleScanResultsAvailable();
-    }
-
-    /** Stops {@link WifiWakeupController}. */
-    public void stop() {
-        if (!mStarted.compareAndSet(true, false)) {
-            return;
-        }
-        if (DEBUG) {
-            Log.d(TAG, "Stopping WifiWakeupController.");
-        }
-        mContext.unregisterReceiver(mBroadcastReceiver);
-        mContentResolver.unregisterContentObserver(mContentObserver);
-    }
-
-    private void handleWifiApStateChanged() {
-        mWifiApState = mWifiManager.getWifiApState();
-        if (VERBOSE) {
-            Log.v(TAG, "handleWifiApStateChanged: " + mWifiApState);
-        }
-    }
-
-    private void handleConfiguredNetworksChanged() {
-        List<WifiConfiguration> wifiConfigurations = mWifiManager.getConfiguredNetworks();
-        if (wifiConfigurations == null) {
-            return;
-        }
-        if (VERBOSE) {
-            Log.v(TAG, "handleConfiguredNetworksChanged: " + wifiConfigurations.size());
-        }
-
-        mSavedNetworks.clear();
-        mSavedSsids.clear();
-        for (int i = 0; i < wifiConfigurations.size(); i++) {
-            WifiConfiguration wifiConfiguration = wifiConfigurations.get(i);
-            if (wifiConfiguration.status != WifiConfiguration.Status.ENABLED
-                    && wifiConfiguration.status != WifiConfiguration.Status.CURRENT) {
-                continue; // Ignore networks that are not connected or enabled.
-            }
-            if (wifiConfiguration.useExternalScores) {
-                continue; // Ignore externally scored networks.
-            }
-            if (wifiConfiguration.hasNoInternetAccess()
-                    || wifiConfiguration.isNoInternetAccessExpected()) {
-                continue; // Ignore networks that will likely not have internet access.
-            }
-            String ssid = WifiConfigurationUtil.removeDoubleQuotes(wifiConfiguration);
-            if (TextUtils.isEmpty(ssid)) {
-                continue;
-            }
-            mSavedNetworks.put(ssid, wifiConfiguration);
-            mSavedSsids.add(ssid);
-        }
-        mSavedSsidsInLastScan.retainAll(mSavedSsids);
-    }
-
-    private void handleWifiStateChanged() {
-        mWifiState = mWifiManager.getWifiState();
-        if (VERBOSE) {
-            Log.v(TAG, "handleWifiStateChanged: " + mWifiState);
-        }
-        switch (mWifiState) {
-            case WifiManager.WIFI_STATE_ENABLED:
-                mSavedSsidsOnDisable.clear();
-                break;
-            case WifiManager.WIFI_STATE_DISABLED:
-                for (String ssid : mSavedSsidsInLastScan) {
-                    mSavedSsidsOnDisable.put(ssid, NUM_SCANS_TO_CONFIRM_AP_LOSS);
-                }
-                break;
-        }
-    }
-
-    private void handleScanResultsAvailable() {
-        List<ScanResult> scanResults = mWifiManager.getScanResults();
-        if (scanResults == null) {
-            return;
-        }
-        if (VERBOSE) {
-            Log.v(TAG, "handleScanResultsAvailable: " + scanResults.size());
-        }
-
-        mSavedSsidsInLastScan.clear();
-        for (int i = 0; i < scanResults.size(); i++) {
-            String ssid = scanResults.get(i).SSID;
-            if (mSavedSsids.contains(ssid)) {
-                mSavedSsidsInLastScan.add(ssid);
-            }
-        }
-
-        if (mAirplaneModeEnabled
-                || mWifiState != WifiManager.WIFI_STATE_DISABLED
-                || mWifiApState != WifiManager.WIFI_AP_STATE_DISABLED) {
-            return;
-        }
-
-        // Update mSavedSsidsOnDisable to remove ssids that the user has moved away from.
-        for (Map.Entry<String, Integer> entry : mSavedSsidsOnDisable.entrySet()) {
-            if (mSavedSsidsInLastScan.contains(entry.getKey())) {
-                mSavedSsidsOnDisable.put(entry.getKey(), NUM_SCANS_TO_CONFIRM_AP_LOSS);
-            } else {
-                if (entry.getValue() > 1) {
-                    mSavedSsidsOnDisable.put(entry.getKey(), entry.getValue() - 1);
-                } else {
-                    mSavedSsidsOnDisable.remove(entry.getKey());
-                }
-            }
-        }
-
-        if (!mSavedSsidsOnDisable.isEmpty()) {
-            if (DEBUG) {
-                Log.d(TAG, "Latest scan result contains ssids from the disabled set: "
-                        + mSavedSsidsOnDisable);
-            }
-            return;
-        }
-
-        WifiConfiguration selectedNetwork = mWifiWakeupNetworkSelector.selectNetwork(mSavedNetworks,
-                scanResults);
-        if (selectedNetwork != null) {
-            if (DEBUG) {
-                Log.d(TAG, "Enabling wifi for ssid: " + selectedNetwork.SSID);
-            }
-            mWifiManager.setWifiEnabled(true /* enabled */);
-            mWifiWakeupNotificationHelper.maybeShowWifiEnabledNotification(selectedNetwork);
-        }
-    }
-
-    void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("mStarted " + mStarted.get());
-        pw.println("mWifiWakeupEnabled: " + mWifiWakeupEnabled);
-        pw.println("mSavedSsids: " + mSavedSsids);
-        pw.println("mSavedSsidsInLastScan: " + mSavedSsidsInLastScan);
-        pw.println("mSavedSsidsOnDisable: " + mSavedSsidsOnDisable);
-    }
-}
diff --git a/src/com/android/networkrecommendation/WifiWakeupNetworkSelector.java b/src/com/android/networkrecommendation/WifiWakeupNetworkSelector.java
deleted file mode 100644
index 94fce56..0000000
--- a/src/com/android/networkrecommendation/WifiWakeupNetworkSelector.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2017 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.networkrecommendation;
-
-import android.content.res.Resources;
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiConfiguration;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * This class determines which network the framework would connect to if Wi-Fi was enabled.
- */
-public class WifiWakeupNetworkSelector {
-    private final int mThresholdQualifiedRssi24;
-    private final int mThresholdQualifiedRssi5;
-    private final int mRssiScoreSlope;
-    private final int mRssiScoreOffset;
-    private final int mPasspointSecurityAward;
-    private final int mSecurityAward;
-    private final int mBand5GHzAward;
-    private final int mThresholdSaturatedRssi24;
-
-    public WifiWakeupNetworkSelector(Resources resources) {
-        mThresholdQualifiedRssi24 = resources.getInteger(
-                R.integer.config_netrec_wifi_score_low_rssi_threshold_24GHz);
-        mThresholdQualifiedRssi5 = resources.getInteger(
-                R.integer.config_netrec_wifi_score_low_rssi_threshold_5GHz);
-        mRssiScoreSlope = resources.getInteger(
-                R.integer.config_netrec_RSSI_SCORE_SLOPE);
-        mRssiScoreOffset = resources.getInteger(
-                R.integer.config_netrec_RSSI_SCORE_OFFSET);
-        mPasspointSecurityAward = resources.getInteger(
-                R.integer.config_netrec_PASSPOINT_SECURITY_AWARD);
-        mSecurityAward = resources.getInteger(
-                R.integer.config_netrec_SECURITY_AWARD);
-        mBand5GHzAward = resources.getInteger(
-                R.integer.config_netrec_5GHz_preference_boost_factor);
-        mThresholdSaturatedRssi24 = resources.getInteger(
-                R.integer.config_netrec_wifi_score_good_rssi_threshold_24GHz);
-    }
-
-    /**
-     * Returns the network that the framework would most likely connect to if Wi-Fi was enabled.
-     */
-    public WifiConfiguration selectNetwork(Map<String, WifiConfiguration> savedNetworks,
-            List<ScanResult> scanResults) {
-        WifiConfiguration candidateWifiConfiguration = null;
-        ScanResult candidateScanResult = null;
-        int candidateScore = -1;
-        for (int i = 0; i < scanResults.size(); i++) {
-            ScanResult scanResult = scanResults.get(i);
-            WifiConfiguration wifiConfiguration = savedNetworks.get(scanResult.SSID);
-            if (wifiConfiguration == null) {
-                continue;
-            }
-            if (ScanResultUtil.is5GHz(scanResult) && scanResult.level < mThresholdQualifiedRssi5
-                    || ScanResultUtil.is24GHz(scanResult)
-                    && scanResult.level < mThresholdQualifiedRssi24) {
-                continue;
-            }
-            if (!ScanResultUtil.doesScanResultMatchWithNetwork(scanResult, wifiConfiguration)) {
-                continue;
-            }
-            int score = calculateScore(scanResult, wifiConfiguration);
-            if (candidateScanResult == null
-                    || calculateScore(scanResult, wifiConfiguration) > candidateScore) {
-                candidateScanResult = scanResult;
-                candidateWifiConfiguration = wifiConfiguration;
-                candidateScore = score;
-            }
-        }
-        return candidateWifiConfiguration;
-    }
-
-    private int calculateScore(ScanResult scanResult, WifiConfiguration wifiConfiguration) {
-        int score = 0;
-        // Calculate the RSSI score.
-        int rssi = scanResult.level <= mThresholdSaturatedRssi24
-                ? scanResult.level : mThresholdSaturatedRssi24;
-        score += (rssi + mRssiScoreOffset) * mRssiScoreSlope;
-
-        // 5GHz band bonus.
-        if (ScanResultUtil.is5GHz(scanResult)) {
-            score += mBand5GHzAward;
-        }
-
-        // Security award.
-        if (wifiConfiguration.isPasspoint()) {
-            score += mPasspointSecurityAward;
-        } else if (!WifiConfigurationUtil.isConfigForOpenNetwork(wifiConfiguration)) {
-            score += mSecurityAward;
-        }
-
-        return score;
-    }
-}
diff --git a/src/com/android/networkrecommendation/WifiWakeupNotificationHelper.java b/src/com/android/networkrecommendation/WifiWakeupNotificationHelper.java
deleted file mode 100644
index e044555..0000000
--- a/src/com/android/networkrecommendation/WifiWakeupNotificationHelper.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2017 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.networkrecommendation;
-
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
-import android.content.res.Resources;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.os.Bundle;
-import android.os.Handler;
-import android.provider.Settings;
-import android.support.annotation.NonNull;
-import android.support.annotation.VisibleForTesting;
-import android.text.TextUtils;
-import android.util.ArraySet;
-import android.util.Log;
-
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Helper class for building and showing notifications for {@link WifiWakeupController}.
- */
-public class WifiWakeupNotificationHelper {
-    private static final String TAG = "WifiWakeupNotifHelper";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    /** Unique ID used for the Wi-Fi Enabled notification. */
-    private static final int NOTIFICATION_ID = R.string.wifi_wakeup_enabled_notification_title;
-    @VisibleForTesting
-    static final String KEY_SHOWN_SSIDS = "key_shown_ssids";
-    private static final String ACTION_DISMISS_WIFI_ENABLED_NOTIFICATION =
-            "com.android.networkrecommendation.ACTION_DISMISS_WIFI_ENABLED_NOTIFICATION";
-    private static final IntentFilter INTENT_FILTER = new IntentFilter();
-    private static final long NETWORK_CONNECTED_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(30);
-
-    static {
-        INTENT_FILTER.addAction(ACTION_DISMISS_WIFI_ENABLED_NOTIFICATION);
-        INTENT_FILTER.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
-    }
-
-    private final Context mContext;
-    private final Resources mResources;
-    private final NotificationManager mNotificationManager;
-    private final Handler mHandler;
-    private final WifiManager mWifiManager;
-    private final SharedPreferences mSharedPreferences;
-
-    @VisibleForTesting
-    final Runnable mCancelNotification = new Runnable() {
-        @Override
-        public void run() {
-            cancelNotificationAndUnregisterReceiver();
-        }
-    };
-
-    @VisibleForTesting
-    final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (ACTION_DISMISS_WIFI_ENABLED_NOTIFICATION.equals(intent.getAction())) {
-                cancelNotificationAndUnregisterReceiver();
-            } else if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) {
-                networkStateChanged();
-            }
-        }
-    };
-    private boolean mNotificationShown;
-    private String mConnectedSsid;
-
-    public WifiWakeupNotificationHelper(Context context, Resources resources, Handler handler,
-            NotificationManager notificationManager, WifiManager wifiManager) {
-        this(context, resources, handler, notificationManager, wifiManager,
-                context.getSharedPreferences("wifi_wakeup", Context.MODE_PRIVATE));
-    }
-
-    @VisibleForTesting
-    WifiWakeupNotificationHelper(Context context, Resources resources, Handler handler,
-            NotificationManager notificationManager, WifiManager wifiManager,
-            SharedPreferences sharedPreferences) {
-        mContext = context;
-        mResources = resources;
-        mNotificationManager = notificationManager;
-        mHandler = handler;
-        mWifiManager = wifiManager;
-        mSharedPreferences = sharedPreferences;
-        mNotificationShown = false;
-        mConnectedSsid = null;
-    }
-
-    /**
-     * Show a notification that Wi-Fi has been enabled by Wi-Fi Wakeup.
-     *
-     * @param wifiConfiguration the {@link WifiConfiguration} that triggered Wi-Fi to wakeup
-     */
-    public void maybeShowWifiEnabledNotification(@NonNull WifiConfiguration wifiConfiguration) {
-        Set<String> ssidSet = mSharedPreferences.getStringSet(KEY_SHOWN_SSIDS, null);
-        if (ssidSet == null) {
-            ssidSet = new ArraySet<>();
-        } else if (ssidSet.contains(wifiConfiguration.SSID)) {
-            if (DEBUG) {
-                Log.d(TAG, "Already showed Wi-Fi Enabled notification for ssid: "
-                        + wifiConfiguration.SSID);
-            }
-            return;
-        }
-        ssidSet.add(wifiConfiguration.SSID);
-        mSharedPreferences.edit().putStringSet(KEY_SHOWN_SSIDS, ssidSet).apply();
-
-        String title = mResources.getString(
-                R.string.wifi_wakeup_enabled_notification_title);
-        String summary = mResources.getString(
-                R.string.wifi_wakeup_enabled_notification_context, wifiConfiguration.SSID);
-        PendingIntent savedNetworkSettingsPendingIntent = PendingIntent.getActivity(mContext, 0,
-                // TODO(b/34135303): update action
-                new Intent(Settings.ACTION_WIFI_SETTINGS),
-                PendingIntent.FLAG_UPDATE_CURRENT);
-        PendingIntent deletePendingIntent = PendingIntent.getActivity(mContext, 0,
-                new Intent(ACTION_DISMISS_WIFI_ENABLED_NOTIFICATION),
-                PendingIntent.FLAG_UPDATE_CURRENT);
-        Bundle extras = new Bundle();
-        extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
-                mResources.getString(R.string.android_system_label));
-        Notification notification = new Notification.Builder(mContext)
-                .setContentTitle(title)
-                .setSmallIcon(R.drawable.ic_wifi_signal_4)
-                .setStyle(new Notification.BigTextStyle().bigText(summary))
-                .setAutoCancel(true)
-                .setDeleteIntent(deletePendingIntent)
-                .setPriority(Notification.PRIORITY_LOW)
-                .setVisibility(Notification.VISIBILITY_PUBLIC)
-                .setCategory(Notification.CATEGORY_STATUS)
-                .setContentIntent(savedNetworkSettingsPendingIntent)
-                .addExtras(extras)
-                .build();
-        mNotificationManager.notify(TAG, NOTIFICATION_ID, notification);
-        mNotificationShown = true;
-        mContext.registerReceiver(mBroadcastReceiver, INTENT_FILTER, null /* broadcastPermission*/,
-                mHandler);
-        mHandler.postDelayed(mCancelNotification, NETWORK_CONNECTED_TIMEOUT_MILLIS);
-    }
-
-    private void cancelNotificationAndUnregisterReceiver() {
-        if (mNotificationShown) {
-            mNotificationShown = false;
-            mConnectedSsid = null;
-            mNotificationManager.cancel(TAG, NOTIFICATION_ID);
-            mContext.unregisterReceiver(mBroadcastReceiver);
-        }
-    }
-
-    private void networkStateChanged() {
-        if (!mWifiManager.isWifiEnabled()) {
-            cancelNotificationAndUnregisterReceiver();
-            return;
-        }
-
-        WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
-        String ssid = wifiInfo == null ? null : wifiInfo.getSSID();
-        if (mConnectedSsid == null) {
-            mConnectedSsid = ssid;
-            mHandler.removeCallbacks(mCancelNotification);
-        } else {
-            if (!TextUtils.equals(ssid, mConnectedSsid)) {
-                cancelNotificationAndUnregisterReceiver();
-            }
-        }
-    }
-}
diff --git a/src/com/android/networkrecommendation/config/Csv.java b/src/com/android/networkrecommendation/config/Csv.java
new file mode 100644
index 0000000..35b6182
--- /dev/null
+++ b/src/com/android/networkrecommendation/config/Csv.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2009 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.networkrecommendation.config;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Utilities for parsing and serializing Comma-Separated Value data.
+ * See http://en.wikipedia.org/wiki/Comma-separated_values and
+ * http://tools.ietf.org/html/rfc4180 for details of the format.
+ */
+public class Csv {
+    /** Field delimiter.  The C in CSV. */
+    public static final String COMMA = ",";
+
+    /** Record delimiter.  "Proper" CSV uses CR-LF, but that would be annoying. */
+    public static final String NEWLINE = "\n";
+
+    /**
+     * Appends a single value to an output string.  If the value
+     * contains quotes, commas, newlines, or leading or trailing whitespace,
+     * the value will be written in quotes (with internal quotes doubled).
+     * Newlines are converted to standard CR-LF form.  This function does not
+     * write field delimiters -- append {@link COMMA} yourself between values.
+     *
+     * @param value to write, quoted as necessary; must be non-null.
+     * @param output to append (possibly quoted) value to
+     * @throws java.io.IOException if writing to 'output' fails
+     */
+    public static void writeValue(String value, Appendable output) throws IOException {
+        int len = value.length();
+        if (len == 0) return;
+
+        char first = value.charAt(0);
+        char last = value.charAt(len - 1);
+        if (first != ' ' && first != '\t' && last != ' ' && last != '\t' &&
+                value.indexOf('"') < 0 && value.indexOf(',') < 0 &&
+                value.indexOf('\r') < 0 && value.indexOf('\n') < 0) {
+            // No quoting needed.
+            output.append(value);
+            return;
+        }
+
+        output.append('"').append(value.replace("\"", "\"\"")).append('"');
+    }
+
+    /**
+     * Parse a record of comma separated values from an input file.
+     * May read multiple physical lines if values contain embedded newlines.
+     *
+     * @param reader to read one or more physical lines from
+     * @param out array to append unquoted CSV values to
+     * @return true if values were read, false on EOF
+     * @throws java.io.IOException if reading from 'reader' fails
+     */
+    public static boolean parseLine(BufferedReader reader, List<String> out) throws IOException {
+        String text = reader.readLine();
+        if (text == null) return false;
+
+        int pos = 0;
+        do {
+            StringBuilder buf = new StringBuilder();
+            int comma;
+            for (;;) {
+                comma = text.indexOf(',', pos);
+                int quote = text.indexOf('"', pos);
+                if (quote == -1 || (comma != -1 && comma < quote)) break;
+
+                if (pos > 0 && text.charAt(pos - 1) == '"') buf.append('"');
+                buf.append(text, pos, quote);
+                while ((quote = text.indexOf('"', (pos = quote + 1))) == -1) {
+                    buf.append(text, pos, text.length()).append('\n');
+                    text = reader.readLine();
+                    if (text == null) {
+                        out.add(buf.toString());
+                        return true;
+                    }
+                    quote = -1;
+                }
+
+                buf.append(text, pos, quote);
+                pos = quote + 1;
+            }
+
+            buf.append(text, pos, comma == -1 ? text.length() : comma);
+            out.add(buf.toString());
+            pos = comma + 1;
+        } while (pos > 0);
+        return true;
+    }
+
+    private Csv() {}  // Do not instantiate
+}
diff --git a/src/com/android/networkrecommendation/config/Flag.java b/src/com/android/networkrecommendation/config/Flag.java
new file mode 100644
index 0000000..953fb1e
--- /dev/null
+++ b/src/com/android/networkrecommendation/config/Flag.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 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.networkrecommendation.config;
+
+/**
+ * Simple configuration parameters for application behavior.
+ * @param <T> A type for a flag value.
+ */
+public class Flag<T> {
+
+    private final T mDefaultValue;
+    private T mOverride;
+
+    public Flag(T defaultValue) {
+        mDefaultValue = defaultValue;
+        mOverride = null;
+    }
+
+    /** Get the currently set flag value. */
+    public T get() {
+        return mOverride != null ? mOverride : mDefaultValue;
+    }
+
+    /** Force a value for testing. */
+    public void override(T value) {
+        mOverride = value;
+    }
+
+    /** Ensure flag state is initialized for tests. */
+    public static void initForTest() {
+    }
+}
diff --git a/src/com/android/networkrecommendation/config/G.java b/src/com/android/networkrecommendation/config/G.java
new file mode 100644
index 0000000..b256f25
--- /dev/null
+++ b/src/com/android/networkrecommendation/config/G.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 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.networkrecommendation.config;
+
+/** Application behavior parameters. */
+public final class G {
+
+    /**
+     * Configurations related to general behaviors of the netrec module, not tied to a specific
+     * feature.
+     */
+    public interface Netrec {
+        Flag<Boolean> enableSensitiveLogging = new Flag(false);
+        Flag<String> wideAreaNetworks = new Flag("xfinitywifi,XFINITY");
+    }
+
+    private G() {}
+}
diff --git a/src/com/android/networkrecommendation/config/PreferenceFile.java b/src/com/android/networkrecommendation/config/PreferenceFile.java
new file mode 100644
index 0000000..9066a6a
--- /dev/null
+++ b/src/com/android/networkrecommendation/config/PreferenceFile.java
@@ -0,0 +1,299 @@
+/*
+ * Copyright (C) 2017 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.networkrecommendation.config;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.os.Build;
+
+import java.util.Collection;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Utility class for retrieving and storing key/value pairs in a SharedPreferences file.
+ *
+ * Typical usage:
+ *
+ * In your application's onCreate();
+ * PreferenceFile.init(this);
+ *
+ * In common preferences declaration area:
+ * private static final PreferenceFile sFile = new PreferenceFile("my_prefs");
+ * public static final SharedPreference<String> pageUrl = sFile.value("page_url", "http://blah");
+ *
+ * At usage time:
+ * String pageUrl = Preferences.pageUrl.get();
+ * Preferences.pageUrl.put("http://www.newurl.com/");
+ */
+public class PreferenceFile {
+    private static final String TAG = "PreferenceFile";
+
+    private static Context sContext;
+
+    public static void init(Context context) {
+        sContext = context;
+    }
+
+    private final String mName;
+    private final int mMode;
+
+    @SuppressWarnings("deprecation")
+    public PreferenceFile(String name) {
+        this(name, Context.MODE_PRIVATE);
+    }
+
+    /**
+     * @deprecated any mode other than MODE_PRIVATE is a bad idea. If you need multi-process
+     * support, see if {@link MultiProcessPreferenceFile} is suitable.
+     */
+    @Deprecated
+    public PreferenceFile(String name, int mode) {
+        mName = name;
+        mMode = mode;
+    }
+
+    /**
+     * Returns a text dump of all preferences in this file; for debugging.
+     */
+    public String dump() {
+        SharedPreferences sp = open();
+        Map<String, ?> allPrefs = sp.getAll();
+        String format = "%" + longestString(allPrefs.keySet()) + "s = %s\n";
+        StringBuilder s = new StringBuilder();
+        for (String key : allPrefs.keySet()) {
+            s.append(String.format(Locale.US, format, key, allPrefs.get(key)));
+        }
+        return s.toString();
+    }
+
+    /** Return a SharedPreferences for this file. */
+    public SharedPreferences open() {
+        return sContext.getSharedPreferences(mName, mMode);
+    }
+
+    public void remove(SharedPreference<?>... preferences) {
+        SharedPreferences.Editor editor = open().edit();
+        for (SharedPreference<?> preference : preferences) {
+            editor.remove(preference.getKey());
+        }
+        commit(editor);
+    }
+
+    /** Synchronously clear all SharedPreferences in this file. */
+    public void clear() {
+        open().edit().clear().commit();
+    }
+
+
+    /**
+     * If on API >= 9, use the asynchronous
+     * {@link Editor#apply()} method. Otherwise, use the
+     * synchronous {@link Editor#commit()} method. <br />
+     * <br />
+     * If commit() is used, the result will be returned. If apply() is used, it
+     * will always return true.
+     *
+     * @param editor The editor to save
+     * @return the result of commit() on API &lt; 9 and true on API >= 9.
+     */
+    @SuppressLint("NewApi")
+    public static boolean commit(Editor editor) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) {
+            return editor.commit();
+        }
+        editor.apply();
+        return true;
+    }
+
+    /** Define a new Long value shared pref key. */
+    public SharedPreference<Long> longValue(final String key, final Long defaultValue) {
+        return new SharedPreference<Long>(this, key) {
+            @Override
+            protected Long read(SharedPreferences sp) {
+                if (sp.contains(key)) {
+                    return sp.getLong(key, 0L);
+                }
+                return defaultValue;
+            }
+
+            @Override
+            protected void write(Editor editor, Long value) {
+                if (value == null) {
+                    throw new IllegalArgumentException("null cannot be written for Long");
+                }
+                editor.putLong(key, value);
+            }
+        };
+    }
+
+    /** Define a new String value shared pref key. */
+    public SharedPreference<String> stringValue(final String key, final String defaultValue) {
+        return new SharedPreference<String>(this, key) {
+            @Override
+            protected String read(SharedPreferences sp) {
+                if (sp.contains(key)) {
+                    return sp.getString(key, null);
+                }
+                return defaultValue;
+            }
+
+            @Override
+            protected void write(Editor editor, String value) {
+                if (value == null) {
+                    throw new IllegalArgumentException("null cannot be written for String");
+                }
+                editor.putString(key, value);
+            }
+        };
+    }
+
+    /** Define a new Boolean value shared pref key. */
+    public SharedPreference<Boolean> booleanValue(final String key, final Boolean defaultValue) {
+        return new SharedPreference<Boolean>(this, key) {
+            @Override
+            protected Boolean read(SharedPreferences sp) {
+                if (sp.contains(key)) {
+                    return sp.getBoolean(key, false);
+                }
+                return defaultValue;
+            }
+
+            @Override
+            protected void write(Editor editor, Boolean value) {
+                if (value == null) {
+                    throw new IllegalArgumentException("null cannot be written for Boolean");
+                }
+                editor.putBoolean(key, value);
+            }
+        };
+    }
+
+    /** Define a new Integer value shared pref key. */
+    public SharedPreference<Integer> intValue(final String key, final Integer defaultValue) {
+        return new SharedPreference<Integer>(this, key) {
+            @Override
+            protected Integer read(SharedPreferences sp) {
+                if (sp.contains(key)) {
+                    return sp.getInt(key, 0);
+                }
+                return defaultValue;
+            }
+
+            @Override
+            protected void write(Editor editor, Integer value) {
+                if (value == null) {
+                    throw new IllegalArgumentException("null cannot be written for Integer");
+                }
+                editor.putInt(key, value);
+            }
+        };
+    }
+
+    /** Define a new Set<String> value shared pref key. */
+    public SharedPreference<Set<String>> stringSetValue(final String key,
+            final Set<String> defaultValue) {
+        return new SharedPreference<Set<String>>(this, key) {
+            @Override
+            protected Set<String> read(SharedPreferences sp) {
+                if (sp.contains(key)) {
+                    return sp.getStringSet(key, null);
+                }
+                return defaultValue;
+            }
+
+            @Override
+            protected void write(Editor editor, Set<String> value) {
+                if (value == null) {
+                    throw new IllegalArgumentException("null cannot be written for Set<String>");
+                }
+                editor.putStringSet(key, value);
+            }
+        };
+    }
+
+    /**
+     * A class representing a key/value pair in a given {@link PreferenceFile}.
+     */
+    public static abstract class SharedPreference<T> {
+        PreferenceFile mFile;
+        final String mKey;
+
+        protected SharedPreference(PreferenceFile file, String key) {
+            mFile = file;
+            mKey = key;
+        }
+
+        /** Read the value stored for this pref, or the default value if none is stored. */
+        public final T get() {
+            return read(mFile.open());
+        }
+
+        /** Get the representation in string of the value for this pref. */
+        public String getValueString() {
+            T value = get();
+            if (value == null) {
+                return null;
+            }
+            return value.toString();
+        }
+
+        /** Return this pref's key. */
+        public final String getKey() {
+            return mKey;
+        }
+
+        /** Return true if this key is defined in its file. */
+        public final boolean exists() {
+            return mFile.open().contains(mKey);
+        }
+
+        /** Write a new value for this pref to its file. */
+        public final void put(T value) {
+            SharedPreferences sp = mFile.open();
+            Editor editor = sp.edit();
+            write(editor, value);
+            commit(editor);
+        }
+
+        /** Removes this pref from its file. */
+        public final void remove() {
+            commit(mFile.open().edit().remove(mKey));
+        }
+
+        /** Override the PreferenceFile used by this preference (for testing). */
+        public final void override(PreferenceFile file) {
+            mFile = file;
+        }
+
+        protected abstract T read(SharedPreferences sp);
+        protected abstract void write(Editor editor, T value);
+    }
+
+    /**
+     * Returns the length of the longest string in the provided Collection.
+     */
+    private static int longestString(Collection<String> strings) {
+        int longest = 0;
+        for (String s : strings) {
+            longest = Math.max(longest, s.length());
+        }
+        return longest;
+    }
+}
diff --git a/src/com/android/networkrecommendation/config/Preferences.java b/src/com/android/networkrecommendation/config/Preferences.java
new file mode 100644
index 0000000..a9e6fb0
--- /dev/null
+++ b/src/com/android/networkrecommendation/config/Preferences.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2017 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.networkrecommendation.config;
+
+import com.android.networkrecommendation.config.PreferenceFile.SharedPreference;
+import java.util.Collections;
+import java.util.Set;
+
+/** The NetRec preferences file. */
+public final class Preferences {
+    private Preferences() {}
+
+    private static final PreferenceFile sPrefs =
+            new PreferenceFile("com.android.networkrecommendation");
+
+    /**
+     * {@link ScoreNetworksChimeraBroadcastReceiver} sets this to true when the scorer is enabled.
+     * {@link com.android.networkrecommendation.scoring.service.FutureRefreshRequestor} checks for
+     * this value and triggers a quick score refresh if this is set.
+     */
+    public static final SharedPreference<Boolean> justEnabled =
+            sPrefs.booleanValue("justEnabled", false);
+
+    /**
+     * The next time, in ms since system boot, that a rapid (i.e. outside the usual refresh window)
+     * will be allowed to make a network request.
+     */
+    public static final SharedPreference<Long> nextRapidRefreshAllowed =
+            sPrefs.longValue("nextRapidRefreshAllowedMillis", 0L);
+
+    /**
+     * The set of saved ssid hashes in previous scan result list when the user disabled Wi-Fi. Saved
+     * to preferences when {@link com.android.networkrecommendation.wakeup.WifiWakeupController}
+     * stops.
+     */
+    public static final SharedPreference<Set<String>> savedSsidsOnDisable =
+            sPrefs.stringSetValue("savedSsidsOnDisable", Collections.emptySet());
+
+    /**
+     * The set of saved ssid hashes that were previously shown as Wi-Fi Enabled notifications
+     * through {@link com.android.networkrecommendation.wakeup.WifiWakeupController}.
+     */
+    public static final SharedPreference<Set<String>> ssidsForWakeupShown =
+            sPrefs.stringSetValue("ssidsForWakeupShown", Collections.emptySet());
+
+    /** Key for {@link com.android.networkrecommendation.storage.Encrypter} on pre-MNC devices. */
+    public static final SharedPreference<String> encrypterKey =
+            sPrefs.stringValue("encrypterKey", null);
+
+    /**
+     * How long we should wait before requesting another network. Used by {@link
+     * PersistentNetworkRequest} to support GCS/WFA.
+     */
+    public static final SharedPreference<Integer> nextNetworkRequestDelayMs =
+            sPrefs.intValue("nextNetworkRequestDelayMs", 0);
+
+    /**
+     * Hash of the SSID that last satisfied the network request in {@link PersistentNetworkRequest}.
+     */
+    public static final SharedPreference<String> lastSsidHash =
+            sPrefs.stringValue("lastSsidHash", "");
+}
diff --git a/src/com/android/networkrecommendation/config/WideAreaNetworks.java b/src/com/android/networkrecommendation/config/WideAreaNetworks.java
new file mode 100644
index 0000000..1a33559
--- /dev/null
+++ b/src/com/android/networkrecommendation/config/WideAreaNetworks.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2017 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.networkrecommendation.config;
+
+import static com.android.networkrecommendation.Constants.TAG;
+
+import android.support.annotation.VisibleForTesting;
+import com.android.networkrecommendation.config.G.Netrec;
+import com.android.networkrecommendation.util.Blog;
+import com.google.common.collect.ImmutableSet;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+
+/** Provides a list of known wide area networks. */
+public class WideAreaNetworks {
+    private WideAreaNetworks() {}
+
+    private static ImmutableSet<String> sWideAreaNetworks;
+
+    /** Initialize the list of wide area networks from the phenotype flag. */
+    public static void init() {
+        sWideAreaNetworks = parseFlag();
+    }
+
+    /**
+     * @param ssid canonical SSID for a network (with quotes removed)
+     * @return {@code true} if {@code ssid} is in the set of wide area networks.
+     */
+    public static boolean contains(String ssid) {
+        if (sWideAreaNetworks == null) {
+            init();
+        }
+        return sWideAreaNetworks.contains(ssid);
+    }
+
+    @VisibleForTesting
+    static ImmutableSet<String> parseFlag() {
+        List<String> parts = new ArrayList<>();
+        BufferedReader reader = new BufferedReader(new StringReader(Netrec.wideAreaNetworks.get()));
+        try {
+            Csv.parseLine(reader, parts);
+        } catch (IOException ex) {
+            Blog.e(TAG, ex, "Error parsing flag");
+        }
+        return ImmutableSet.copyOf(parts);
+    }
+}
diff --git a/src/com/android/networkrecommendation/notify/WifiNotificationController.java b/src/com/android/networkrecommendation/notify/WifiNotificationController.java
new file mode 100644
index 0000000..c134b47
--- /dev/null
+++ b/src/com/android/networkrecommendation/notify/WifiNotificationController.java
@@ -0,0 +1,590 @@
+/*
+ * Copyright (C) 2017 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.networkrecommendation.notify;
+
+import static com.android.networkrecommendation.Constants.TAG;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+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.NetworkScoreManager;
+import android.net.RecommendationRequest;
+import android.net.RecommendationResult;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.support.annotation.IntDef;
+import android.support.annotation.Nullable;
+import com.android.networkrecommendation.R;
+import com.android.networkrecommendation.SynchronousNetworkRecommendationProvider;
+import com.android.networkrecommendation.util.Blog;
+import com.android.networkrecommendation.util.RoboCompatUtil;
+import com.android.networkrecommendation.util.ScanResultUtil;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/** Takes care of handling the "open wi-fi network available" notification */
+public class WifiNotificationController {
+    /** The unique ID of the Notification given to the NotificationManager. */
+    private static final int NOTIFICATION_ID = R.string.wifi_available_title;
+
+    /** When a notification is shown, we wait this amount before possibly showing it again. */
+    private final long mNotificationRepeatDelayMs;
+
+    /** Whether the user has set the setting to show the 'available networks' notification. */
+    private boolean mNotificationEnabled;
+
+    /** Whether the user has {@link UserManager#DISALLOW_CONFIG_WIFI} restriction. */
+    private boolean mWifiConfigRestricted;
+
+    /** Observes the user setting to keep {@link #mNotificationEnabled} in sync. */
+    private final NotificationEnabledSettingObserver mNotificationEnabledSettingObserver;
+
+    /**
+     * The {@link System#currentTimeMillis()} must be at least this value for us to show the
+     * notification again.
+     */
+    private long mNotificationRepeatTime;
+
+    /** These are all of the possible states for the open networks available notification. */
+    @IntDef({
+        State.NO_RECOMMENDATION,
+        State.SHOWING_RECOMMENDATION_NOTIFICATION,
+        State.CONNECTING_IN_NOTIFICATION,
+        State.CONNECTING_IN_WIFI_PICKER,
+        State.CONNECTED,
+        State.CONNECT_FAILED
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface State {
+        int NO_RECOMMENDATION = 0;
+        int SHOWING_RECOMMENDATION_NOTIFICATION = 1;
+        int CONNECTING_IN_NOTIFICATION = 2;
+        int CONNECTING_IN_WIFI_PICKER = 3;
+        int CONNECTED = 4;
+        int CONNECT_FAILED = 5;
+    }
+
+    /**
+     * The {@link System#currentTimeMillis()} must be at least this value to log that open networks
+     * are available.
+     */
+    private long mOpenNetworksLoggingRepeatTime;
+
+    /** Current state of the notification. */
+    @State private int mState = State.NO_RECOMMENDATION;
+
+    /**
+     * The number of continuous scans that must occur before consider the supplicant in a scanning
+     * state. This allows supplicant to associate with remembered networks that are in the scan
+     * results.
+     */
+    private static final int NUM_SCANS_BEFORE_ACTUALLY_SCANNING = 3;
+
+    /**
+     * The number of scans since the last network state change. When this exceeds {@link
+     * #NUM_SCANS_BEFORE_ACTUALLY_SCANNING}, we consider the supplicant to actually be scanning.
+     * When the network state changes to something other than scanning, we reset this to 0.
+     */
+    private int mNumScansSinceNetworkStateChange;
+
+    /** Time in milliseconds to display the Connecting notification. */
+    private static final int TIME_TO_SHOW_CONNECTING_MILLIS = 10000;
+
+    /** Time in milliseconds to display the Connected notification. */
+    private static final int TIME_TO_SHOW_CONNECTED_MILLIS = 5000;
+
+    /** Time in milliseconds to display the Failed To Connect notification. */
+    private static final int TIME_TO_SHOW_FAILED_MILLIS = 5000;
+
+    /** Try to connect to the recommended WifiConfiguration and also open the wifi picker. */
+    static final String ACTION_CONNECT_TO_RECOMMENDED_NETWORK_AND_OPEN_SETTINGS =
+            "com.android.networkrecommendation.notify.CONNECT_TO_RECOMMENDED_NETWORK_AND_OPEN_SETTINGS";
+
+    /** Try to connect to the recommended WifiConfiguration. */
+    static final String ACTION_CONNECT_TO_RECOMMENDED_NETWORK =
+            "com.android.networkrecommendation.notify.CONNECT_TO_RECOMMENDED_NETWORK";
+
+    /** Open wifi picker to see all available networks. */
+    static final String ACTION_PICK_WIFI_NETWORK =
+            "com.android.networkrecommendation.notify.ACTION_PICK_WIFI_NETWORK";
+
+    /** Open wifi picker to see all networks after connect to the recommended network failed. */
+    static final String ACTION_PICK_WIFI_NETWORK_AFTER_CONNECT_FAILURE =
+            "com.android.networkrecommendation.notify.ACTION_PICK_WIFI_NETWORK_AFTER_CONNECT_FAILURE";
+
+    /** Handles behavior when notification is deleted. */
+    static final String ACTION_NOTIFICATION_DELETED =
+            "com.android.networkrecommendation.notify.NOTIFICATION_DELETED";
+
+    /** Network recommended by {@link NetworkScoreManager#requestRecommendation}. */
+    private WifiConfiguration mRecommendedNetwork;
+
+    /** Whether {@link WifiNotificationController} has been started. */
+    private final AtomicBoolean mStarted;
+
+    private static final String NOTIFICATION_TAG = "WifiNotification";
+
+    private final Context mContext;
+    private final Handler mHandler;
+    private final ContentResolver mContentResolver;
+    private final SynchronousNetworkRecommendationProvider mNetworkRecommendationProvider;
+    private final WifiManager mWifiManager;
+    private final NotificationManager mNotificationManager;
+    private final UserManager mUserManager;
+    private final WifiNotificationHelper mWifiNotificationHelper;
+    private NetworkInfo mNetworkInfo;
+    private NetworkInfo.DetailedState mDetailedState;
+    private volatile int mWifiState;
+
+    public WifiNotificationController(
+            Context context,
+            ContentResolver contentResolver,
+            Handler handler,
+            SynchronousNetworkRecommendationProvider networkRecommendationProvider,
+            WifiManager wifiManager,
+            NotificationManager notificationManager,
+            UserManager userManager,
+            WifiNotificationHelper helper) {
+        mContext = context;
+        mContentResolver = contentResolver;
+        mNetworkRecommendationProvider = networkRecommendationProvider;
+        mWifiManager = wifiManager;
+        mNotificationManager = notificationManager;
+        mUserManager = userManager;
+        mHandler = handler;
+        mWifiNotificationHelper = helper;
+        mStarted = new AtomicBoolean(false);
+
+        // Setting is in seconds
+        mNotificationRepeatDelayMs =
+                TimeUnit.SECONDS.toMillis(
+                        Settings.Global.getInt(
+                                contentResolver,
+                                Settings.Global.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY,
+                                900));
+        mNotificationEnabledSettingObserver = new NotificationEnabledSettingObserver(mHandler);
+    }
+
+    /** Starts {@link WifiNotificationController}. */
+    public void start() {
+        if (!mStarted.compareAndSet(false, true)) {
+            return;
+        }
+
+        mWifiState = mWifiManager.getWifiState();
+        mDetailedState = NetworkInfo.DetailedState.IDLE;
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
+        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+        filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
+        filter.addAction(RoboCompatUtil.ACTION_USER_RESTRICTIONS_CHANGED);
+        filter.addAction(ACTION_CONNECT_TO_RECOMMENDED_NETWORK_AND_OPEN_SETTINGS);
+        filter.addAction(ACTION_CONNECT_TO_RECOMMENDED_NETWORK);
+        filter.addAction(ACTION_NOTIFICATION_DELETED);
+        filter.addAction(ACTION_PICK_WIFI_NETWORK);
+        filter.addAction(ACTION_PICK_WIFI_NETWORK_AFTER_CONNECT_FAILURE);
+
+        mContext.registerReceiver(
+                mBroadcastReceiver, filter, null /* broadcastPermission */, mHandler);
+        mNotificationEnabledSettingObserver.register();
+
+        handleUserRestrictionsChanged();
+    }
+
+    /** Stops {@link WifiNotificationController}. */
+    public void stop() {
+        if (!mStarted.compareAndSet(true, false)) {
+            return;
+        }
+        mContext.unregisterReceiver(mBroadcastReceiver);
+        mNotificationEnabledSettingObserver.unregister();
+    }
+
+    private final BroadcastReceiver mBroadcastReceiver =
+            new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    try {
+                        switch (intent.getAction()) {
+                            case WifiManager.WIFI_STATE_CHANGED_ACTION:
+                                mWifiState = mWifiManager.getWifiState();
+                                resetNotification();
+                                break;
+                            case WifiManager.NETWORK_STATE_CHANGED_ACTION:
+                                handleNetworkStateChange(intent);
+                                break;
+                            case WifiManager.SCAN_RESULTS_AVAILABLE_ACTION:
+                                checkAndSetNotification(mNetworkInfo);
+                                break;
+                            case RoboCompatUtil.ACTION_USER_RESTRICTIONS_CHANGED:
+                                handleUserRestrictionsChanged();
+                                break;
+                            case ACTION_CONNECT_TO_RECOMMENDED_NETWORK_AND_OPEN_SETTINGS:
+                                connectToRecommendedNetwork();
+                                openWifiPicker();
+                                updateOnConnecting(false /* showNotification*/);
+                                break;
+                            case ACTION_CONNECT_TO_RECOMMENDED_NETWORK:
+                                connectToRecommendedNetwork();
+                                updateOnConnecting(true /* showNotification*/);
+                                break;
+                            case ACTION_NOTIFICATION_DELETED:
+                                handleNotificationDeleted();
+                                break;
+                            case ACTION_PICK_WIFI_NETWORK:
+                                openWifiPicker();
+                                break;
+                            case ACTION_PICK_WIFI_NETWORK_AFTER_CONNECT_FAILURE:
+                                openWifiPicker();
+                                break;
+                            default:
+                                Blog.e(
+                                        TAG,
+                                        "Unexpected broadcast. [action=%s]",
+                                        intent.getAction());
+                        }
+
+                    } catch (RuntimeException re) {
+                        // TODO(b/35044022) Remove try/catch after a couple of releases when we are confident
+                        // this is not going to throw.
+                        Blog.e(TAG, re, "RuntimeException in broadcast receiver.");
+                    }
+                }
+            };
+
+    private void handleNetworkStateChange(Intent intent) {
+        mNetworkInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
+        NetworkInfo.DetailedState detailedState = mNetworkInfo.getDetailedState();
+        if (detailedState != NetworkInfo.DetailedState.SCANNING
+                && detailedState != mDetailedState) {
+            mDetailedState = detailedState;
+            switch (mDetailedState) {
+                case CONNECTED:
+                    updateOnConnect();
+                    break;
+                case DISCONNECTED:
+                case CAPTIVE_PORTAL_CHECK:
+                    resetNotification();
+                    break;
+
+                    // TODO: figure out if these are failure cases when connecting
+                case IDLE:
+                case SCANNING:
+                case CONNECTING:
+                case DISCONNECTING:
+                case AUTHENTICATING:
+                case OBTAINING_IPADDR:
+                case SUSPENDED:
+                case FAILED:
+                case BLOCKED:
+                case VERIFYING_POOR_LINK:
+                    break;
+            }
+        }
+    }
+
+    private void handleUserRestrictionsChanged() {
+        mWifiConfigRestricted = mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_WIFI);
+        Blog.v(TAG, "handleUserRestrictionsChanged: %b", mWifiConfigRestricted);
+    }
+
+    private void checkAndSetNotification(NetworkInfo networkInfo) {
+        // TODO: unregister broadcast so we do not have to check here
+        // If we shouldn't place a notification on available networks, then
+        // don't bother doing any of the following
+        if (!mNotificationEnabled
+                || mWifiConfigRestricted
+                || mWifiState != WifiManager.WIFI_STATE_ENABLED
+                || mState > State.SHOWING_RECOMMENDATION_NOTIFICATION) {
+            return;
+        }
+
+        NetworkInfo.State state = NetworkInfo.State.DISCONNECTED;
+        if (networkInfo != null) {
+            state = networkInfo.getState();
+        }
+
+        if (state == NetworkInfo.State.DISCONNECTED || state == NetworkInfo.State.UNKNOWN) {
+            maybeLogOpenNetworksAvailable();
+            RecommendationResult result = getOpenNetworkRecommendation();
+            if (result != null && result.getWifiConfiguration() != null) {
+                mRecommendedNetwork = result.getWifiConfiguration();
+
+                if (++mNumScansSinceNetworkStateChange >= NUM_SCANS_BEFORE_ACTUALLY_SCANNING) {
+                    /*
+                     * We have scanned continuously at least
+                     * NUM_SCANS_BEFORE_NOTIFICATION times. The user
+                     * probably does not have a remembered network in range,
+                     * since otherwise supplicant would have tried to
+                     * associate and thus resetting this counter.
+                     */
+                    displayNotification();
+                }
+                return;
+            }
+        }
+
+        // No open networks in range, remove the notification
+        removeNotification();
+    }
+
+    private void maybeLogOpenNetworksAvailable() {
+        long now = System.currentTimeMillis();
+        if (now < mOpenNetworksLoggingRepeatTime) {
+            return;
+        }
+        mOpenNetworksLoggingRepeatTime = now + mNotificationRepeatDelayMs;
+    }
+
+    /**
+     * Uses {@link NetworkScoreManager} to choose a qualified network out of the list of {@link
+     * ScanResult}s.
+     *
+     * @return returns the best qualified open networks, if any.
+     */
+    @Nullable
+    private RecommendationResult getOpenNetworkRecommendation() {
+        List<ScanResult> scanResults = mWifiManager.getScanResults();
+        if (scanResults == null || scanResults.isEmpty()) {
+            return null;
+        }
+
+        ArrayList<ScanResult> openNetworks = new ArrayList<>();
+        List<WifiConfiguration> configuredNetworks = mWifiManager.getConfiguredNetworks();
+        for (ScanResult scanResult : scanResults) {
+            //A capability of [ESS] represents an open access point
+            //that is available for an STA to connect
+            //TODO: potentially handle this within NetworkRecommendationProvider instead.
+            if ("[ESS]".equals(scanResult.capabilities)) {
+                if (isSavedNetwork(scanResult, configuredNetworks)) {
+                    continue;
+                }
+                openNetworks.add(scanResult);
+            }
+        }
+
+        Blog.d(TAG, "Sending RecommendationRequest. [num_open_networks=%d]", openNetworks.size());
+        RecommendationRequest request =
+                new RecommendationRequest.Builder()
+                        .setScanResults(openNetworks.toArray(new ScanResult[openNetworks.size()]))
+                        .build();
+        return mNetworkRecommendationProvider.requestRecommendation(request);
+    }
+
+    /** Returns true if scanResult matches the list of saved networks */
+    private boolean isSavedNetwork(ScanResult scanResult, List<WifiConfiguration> savedNetworks) {
+        if (savedNetworks == null) {
+            return false;
+        }
+        for (int i = 0; i < savedNetworks.size(); i++) {
+            if (ScanResultUtil.doesScanResultMatchWithNetwork(scanResult, savedNetworks.get(i))) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /** Display's a notification that there are open Wi-Fi networks. */
+    private void displayNotification() {
+        // Since we use auto cancel on the notification, when the
+        // mNetworksAvailableNotificationShown is true, the notification may
+        // have actually been canceled.  However, when it is false we know
+        // for sure that it is not being shown (it will not be shown any other
+        // place than here)
+
+        // Not enough time has passed to show the notification again
+        if (mState == State.NO_RECOMMENDATION
+                && System.currentTimeMillis() < mNotificationRepeatTime) {
+            return;
+        }
+        Notification notification =
+                mWifiNotificationHelper.createMainNotification(mRecommendedNetwork);
+        mNotificationRepeatTime = System.currentTimeMillis() + mNotificationRepeatDelayMs;
+        postNotification(notification);
+        if (mState != State.SHOWING_RECOMMENDATION_NOTIFICATION) {
+            mState = State.SHOWING_RECOMMENDATION_NOTIFICATION;
+        }
+    }
+
+    /** Opens activity to allow the user to select a wifi network. */
+    private void openWifiPicker() {
+        // Close notification drawer before opening the picker.
+        mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
+        mContext.startActivity(
+                new Intent(WifiManager.ACTION_PICK_WIFI_NETWORK)
+                        .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+        removeNotification();
+    }
+
+    /** Attempts to connect to recommended network the recommended network. */
+    private void connectToRecommendedNetwork() {
+        if (mRecommendedNetwork == null) {
+            return;
+        }
+        mRecommendedNetwork.BSSID = null;
+
+        // Attempts to connect to recommended network.
+        RoboCompatUtil.getInstance().connectToWifi(mWifiManager, mRecommendedNetwork);
+    }
+
+    private void updateOnConnecting(boolean showNotification) {
+        if (showNotification) {
+            // Update notification to connecting status.
+            Notification notification =
+                    mWifiNotificationHelper.createConnectingNotification(mRecommendedNetwork);
+            postNotification(notification);
+            mState = State.CONNECTING_IN_NOTIFICATION;
+        } else {
+            mState = State.CONNECTING_IN_WIFI_PICKER;
+        }
+        mHandler.postDelayed(
+                () -> {
+                    updateOnFailedToConnect();
+                },
+                TIME_TO_SHOW_CONNECTING_MILLIS);
+    }
+
+    /**
+     * When detailed state changes to CONNECTED, show connected notification or reset notification.
+     */
+    private void updateOnConnect() {
+        if (mState == State.CONNECTING_IN_NOTIFICATION) {
+            Notification notification =
+                    mWifiNotificationHelper.createConnectedNotification(mRecommendedNetwork);
+            postNotification(notification);
+            mState = State.CONNECTED;
+            mHandler.postDelayed(
+                    () -> {
+                        if (mState == State.CONNECTED) {
+                            removeNotification();
+                        }
+                    },
+                    TIME_TO_SHOW_CONNECTED_MILLIS);
+        } else if (mState == State.CONNECTING_IN_WIFI_PICKER) {
+            removeNotification();
+        }
+    }
+
+    /**
+     * Displays the Failed To Connect notification after the Connecting notification is shown for
+     * {@link #TIME_TO_SHOW_CONNECTING_MILLIS} duration.
+     */
+    private void updateOnFailedToConnect() {
+        if (mState == State.CONNECTING_IN_NOTIFICATION) {
+            Notification notification = mWifiNotificationHelper.createFailedToConnectNotification();
+            postNotification(notification);
+            mState = State.CONNECT_FAILED;
+            mHandler.postDelayed(
+                    () -> {
+                        if (mState == State.CONNECT_FAILED) {
+                            removeNotification();
+                        }
+                    },
+                    TIME_TO_SHOW_FAILED_MILLIS);
+        } else if (mState == State.CONNECTING_IN_WIFI_PICKER) {
+            removeNotification();
+        }
+    }
+
+    /** Handles behavior when notification is dismissed. */
+    private void handleNotificationDeleted() {
+        mState = State.NO_RECOMMENDATION;
+        mRecommendedNetwork = null;
+    }
+
+    private void postNotification(Notification notification) {
+        mNotificationManager.notify(NOTIFICATION_TAG, NOTIFICATION_ID, notification);
+    }
+
+    /**
+     * Clears variables related to tracking whether a notification has been shown recently and
+     * clears the current notification.
+     */
+    private void resetNotification() {
+        if (mState != State.NO_RECOMMENDATION) {
+            removeNotification();
+        }
+        mRecommendedNetwork = null;
+        mNotificationRepeatTime = 0;
+        mNumScansSinceNetworkStateChange = 0;
+        mOpenNetworksLoggingRepeatTime = 0;
+    }
+
+    private void removeNotification() {
+        mNotificationManager.cancel(NOTIFICATION_TAG, NOTIFICATION_ID);
+        mState = State.NO_RECOMMENDATION;
+        mRecommendedNetwork = null;
+    }
+
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("mNotificationEnabled " + mNotificationEnabled);
+        pw.println("mNotificationRepeatTime " + mNotificationRepeatTime);
+        pw.println("mState " + mState);
+        pw.println("mNumScansSinceNetworkStateChange " + mNumScansSinceNetworkStateChange);
+    }
+
+    private class NotificationEnabledSettingObserver extends ContentObserver {
+        NotificationEnabledSettingObserver(Handler handler) {
+            super(handler);
+        }
+
+        public void register() {
+            mContentResolver.registerContentObserver(
+                    Settings.Global.getUriFor(
+                            Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON),
+                    true,
+                    this);
+            mNotificationEnabled = getValue();
+        }
+
+        public void unregister() {
+            mContentResolver.unregisterContentObserver(this);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            super.onChange(selfChange);
+
+            mNotificationEnabled = getValue();
+            resetNotification();
+        }
+
+        private boolean getValue() {
+            return Settings.Global.getInt(
+                            mContentResolver,
+                            Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
+                            0)
+                    == 1;
+        }
+    }
+}
diff --git a/src/com/android/networkrecommendation/notify/WifiNotificationHelper.java b/src/com/android/networkrecommendation/notify/WifiNotificationHelper.java
new file mode 100644
index 0000000..b19f25c
--- /dev/null
+++ b/src/com/android/networkrecommendation/notify/WifiNotificationHelper.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2017 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.networkrecommendation.notify;
+
+import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
+import static com.android.networkrecommendation.util.NotificationChannelUtil.CHANNEL_ID_NETWORK_AVAILABLE;
+
+import android.app.Notification;
+import android.app.Notification.Action;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.net.wifi.WifiConfiguration;
+import android.os.Bundle;
+import com.android.networkrecommendation.R;
+import com.android.networkrecommendation.util.NotificationChannelUtil;
+
+/** Helper class that creates notifications for {@link WifiNotificationController}. */
+public class WifiNotificationHelper {
+    private final Context mContext;
+
+    public WifiNotificationHelper(Context context) {
+        mContext = context;
+    }
+
+    /**
+     * Creates the main open networks notification with two actions. "Options" link to the Wi-Fi
+     * picker activity, and "Connect" prompts {@link WifiNotificationController} to connect to the
+     * recommended network. Tapping on the content body connects to the recommended network and
+     * opens the wifi picker
+     */
+    public Notification createMainNotification(WifiConfiguration config) {
+        PendingIntent allNetworksIntent =
+                PendingIntent.getBroadcast(
+                        mContext,
+                        0,
+                        new Intent(WifiNotificationController.ACTION_PICK_WIFI_NETWORK),
+                        FLAG_UPDATE_CURRENT);
+        Action allNetworksAction =
+                new Action.Builder(
+                                null /* icon */,
+                                mContext.getText(R.string.wifi_available_action_all_networks),
+                                allNetworksIntent)
+                        .build();
+        PendingIntent connectIntent =
+                PendingIntent.getBroadcast(
+                        mContext,
+                        0,
+                        new Intent(
+                                WifiNotificationController.ACTION_CONNECT_TO_RECOMMENDED_NETWORK),
+                        FLAG_UPDATE_CURRENT);
+        Action connectAction =
+                new Action.Builder(
+                                null /* icon */,
+                                mContext.getText(R.string.wifi_available_action_connect),
+                                connectIntent)
+                        .build();
+        PendingIntent connectAndOpenPickerIntent =
+                PendingIntent.getBroadcast(
+                        mContext,
+                        0,
+                        new Intent(
+                                WifiNotificationController
+                                        .ACTION_CONNECT_TO_RECOMMENDED_NETWORK_AND_OPEN_SETTINGS),
+                        FLAG_UPDATE_CURRENT);
+        return createNotificationBuilder(R.string.wifi_available_title, config.SSID)
+                .setContentIntent(connectAndOpenPickerIntent)
+                .addAction(connectAction)
+                .addAction(allNetworksAction)
+                .build();
+    }
+
+    /**
+     * Creates the notification that indicates the controller is attempting to connect to the
+     * recommended network.
+     */
+    public Notification createConnectingNotification(WifiConfiguration config) {
+        return createNotificationBuilder(R.string.wifi_available_title_connecting, config.SSID)
+                .setProgress(0 /* max */, 0 /* progress */, true /* indeterminate */)
+                .build();
+    }
+
+    /**
+     * Creates the notification that indicates the controller successfully connected to the
+     * recommended network.
+     */
+    public Notification createConnectedNotification(WifiConfiguration config) {
+        return createNotificationBuilder(R.string.wifi_available_title_connected, config.SSID)
+                .setAutoCancel(true)
+                .build();
+    }
+
+    /**
+     * Creates the notification that indicates the controller failed to connect to the recommended
+     * network. Tapping this notification opens the wifi picker.
+     */
+    public Notification createFailedToConnectNotification() {
+        PendingIntent openWifiPickerAfterFailure =
+                PendingIntent.getBroadcast(
+                        mContext,
+                        0,
+                        new Intent(
+                                WifiNotificationController
+                                        .ACTION_PICK_WIFI_NETWORK_AFTER_CONNECT_FAILURE),
+                        FLAG_UPDATE_CURRENT);
+        return createNotificationBuilder(
+                        R.string.wifi_available_title_failed,
+                        mContext.getString(R.string.wifi_available_content_failed))
+                .setContentIntent(openWifiPickerAfterFailure)
+                .setAutoCancel(true)
+                .build();
+    }
+
+    private Notification.Builder createNotificationBuilder(int titleRid, String content) {
+        CharSequence title = mContext.getText(titleRid);
+        PendingIntent deleteIntent =
+                PendingIntent.getBroadcast(
+                        mContext,
+                        0,
+                        new Intent(WifiNotificationController.ACTION_NOTIFICATION_DELETED),
+                        FLAG_UPDATE_CURRENT);
+        int smallIcon = R.drawable.ic_signal_wifi_statusbar_not_connected;
+        Notification.Builder builder =
+                new Notification.Builder(mContext)
+                        .setDeleteIntent(deleteIntent)
+                        .setSmallIcon(smallIcon)
+                        .setTicker(title)
+                        .setContentTitle(title)
+                        .setColor(mContext.getColor(R.color.color_tint))
+                        .setContentText(content)
+                        .setShowWhen(false)
+                        .setLocalOnly(true)
+                        .addExtras(getOverrideLabelExtras());
+        return NotificationChannelUtil.setChannel(builder, CHANNEL_ID_NETWORK_AVAILABLE);
+    }
+
+    private Bundle getOverrideLabelExtras() {
+        Bundle extras = new Bundle();
+        extras.putString(
+                Notification.EXTRA_SUBSTITUTE_APP_NAME,
+                mContext.getString(R.string.notification_channel_group_name));
+        return extras;
+    }
+}
diff --git a/src/com/android/networkrecommendation/scoring/util/HashUtil.java b/src/com/android/networkrecommendation/scoring/util/HashUtil.java
new file mode 100644
index 0000000..19fbd6a
--- /dev/null
+++ b/src/com/android/networkrecommendation/scoring/util/HashUtil.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2017 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.networkrecommendation.scoring.util;
+
+import android.util.Base64;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/** Hashcode and encoding utils. */
+public final class HashUtil {
+    private HashUtil() {}
+
+    /**
+     * Returns a base64-encoded secure hash (using the SHA-256 algorithm) of the provided input.
+     *
+     * @param input the bytes for which the secure hash should be computed.
+     * @return the hash
+     */
+    public static String secureHash(String input) {
+        return encodeBase64(getHash(input, "SHA-256"));
+    }
+
+    public static String encodeBase64(byte[] input) {
+        return Base64.encodeToString(input, Base64.URL_SAFE | Base64.NO_PADDING | Base64.NO_WRAP);
+    }
+
+    /** Retrieves the message digest instance for a given hash algorithm. */
+    public static MessageDigest getMessageDigest(String hashAlgorithm) {
+        try {
+            return MessageDigest.getInstance(hashAlgorithm);
+        } catch (NoSuchAlgorithmException e) {
+            return null;
+        }
+    }
+
+    /**
+     * @return hash of input using hashAlgorithm, or 0-length byte array if input is null, or null
+     *     if hashAlgorithm can't be loaded
+     */
+    public static byte[] getHash(String input, String hashAlgorithm) {
+        if (input != null) {
+            MessageDigest digest = getMessageDigest(hashAlgorithm);
+            if (digest == null) {
+                return null;
+            }
+            return digest.digest(input.getBytes());
+        }
+        return new byte[0];
+    }
+
+    /**
+     * Gets an SSID-specific hash which also ensures the SSID is in cannonical form (stripped of
+     * quotes).
+     */
+    public static String getSsidHash(String ssid) {
+        return secureHash(NetworkUtil.canonicalizeSsid(ssid));
+    }
+
+    /** Gets a single hash of over the combined SSID and BSSID. */
+    public static String getSsidBssidHash(String ssid, String bssid) {
+        String canonicalSsid = NetworkUtil.canonicalizeSsid(ssid);
+        return secureHash(canonicalSsid + bssid);
+    }
+
+    /** Return the first 8 bytes of the SHA-256 hash of the given ssid as a long value. */
+    public static long hashAsLong(String ssid) {
+        byte[] h = getHash(ssid, "SHA-256");
+        if (h == null || h.length < 8) {
+            return 0;
+        }
+        return (h[0] & 0xFFL) << 56
+                | (h[1] & 0xFFL) << 48
+                | (h[2] & 0xFFL) << 40
+                | (h[3] & 0xFFL) << 32
+                | (h[4] & 0xFFL) << 24
+                | (h[5] & 0xFFL) << 16
+                | (h[6] & 0xFFL) << 8
+                | (h[7] & 0xFFL);
+    }
+}
diff --git a/src/com/android/networkrecommendation/scoring/util/NetworkUtil.java b/src/com/android/networkrecommendation/scoring/util/NetworkUtil.java
new file mode 100644
index 0000000..b27bbe6
--- /dev/null
+++ b/src/com/android/networkrecommendation/scoring/util/NetworkUtil.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2017 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.networkrecommendation.scoring.util;
+
+import static android.net.wifi.WifiConfiguration.KeyMgmt.IEEE8021X;
+import static android.net.wifi.WifiConfiguration.KeyMgmt.WPA_EAP;
+import static android.net.wifi.WifiConfiguration.KeyMgmt.WPA_PSK;
+import static com.android.networkrecommendation.util.ScanResultUtil.isScanResultForOpenNetwork;
+
+import android.content.Context;
+import android.net.NetworkKey;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+import com.android.networkrecommendation.Constants;
+import com.android.networkrecommendation.util.Blog;
+import com.android.networkrecommendation.util.ScanResultUtil;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/** Network Utils. */
+public final class NetworkUtil {
+
+    private NetworkUtil() {
+        // do not instantiate
+    }
+
+    /**
+     * Canonicalize the given SSID returned by WifiInfo#getSSID().
+     *
+     * <p>This method should only be called once on a given SSID! If an SSID contains outer quotes,
+     * we will strip them twice and change the SSID to a different one.
+     *
+     * <p>The SSID should be returned surrounded by double quotation marks if it is valid UTF-8.
+     * This behavior was only implemented correctly after
+     * https://googleplex-android-review.googlesource.com/#/c/224602/ which went into JB-MR1.
+     *
+     * <p>This method does not account for non-UTF-8 SSIDs, which are returned as a string of hex
+     * digits from getSSID().
+     *
+     * <p>For more details, see: http://stackoverflow.com/questions/13563032
+     */
+    public static String canonicalizeSsid(String ssid) {
+        if (ssid == null) {
+            return null;
+        }
+        return removeQuotesIfNeeded(ssid);
+    }
+
+    /** Remove the leading quote and trailing quote. */
+    private static String removeQuotesIfNeeded(String text) {
+        if (text.length() > 1 && text.startsWith("\"") && text.endsWith("\"")) {
+            return text.substring(1, text.length() - 1);
+        }
+        return text;
+    }
+
+    /**
+     * @return a map from NetworkKey to true if that network is open, and false otherwise, for all
+     *     visible networks in the last set of Wi-Fi scan results.
+     */
+    public static Map<NetworkKey, Boolean> getOpenWifiNetworkKeys(Context context) {
+        WifiManager wifiMgr = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+        List<ScanResult> scanResults = null;
+        if (Util.isScorerActive(context)) {
+            try {
+                scanResults = wifiMgr.getScanResults();
+            } catch (SecurityException e) {
+                Blog.w(Constants.TAG, e, "No permission to get scan results");
+                scanResults = null;
+            }
+        }
+        if (scanResults == null) {
+            return Collections.emptyMap();
+        }
+        Map<NetworkKey, Boolean> openKeys = new HashMap<>();
+        for (int i = 0; i < scanResults.size(); i++) {
+            ScanResult scanResult = scanResults.get(i);
+            NetworkKey networkKey = ScanResultUtil.createNetworkKey(scanResult);
+            if (networkKey != null) {
+                openKeys.put(networkKey, isScanResultForOpenNetwork(scanResult));
+            }
+        }
+        return openKeys;
+    }
+
+    /** Returns true if the given config is for an "open" network. */
+    public static boolean isOpenNetwork(@NonNull WifiConfiguration config) {
+        if (config.allowedKeyManagement.get(WPA_PSK) // covers WPA_PSK and WPA2_PSK
+                || config.allowedKeyManagement.get(WPA_EAP)
+                || config.allowedKeyManagement.get(IEEE8021X)
+                || (config.wepKeys != null && config.wepKeys[0] != null)) {
+            return false;
+        }
+        return true;
+    }
+
+    @NonNull
+    public static String getCurrentWifiSsid(Context context) {
+        WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
+        return wifiInfo == null ? "" : wifiInfo.getSSID();
+    }
+
+    /** Returns the config for the given SSID, or null if one cannot be found. */
+    @Nullable
+    public static WifiConfiguration getConfig(Context context, String ssid) {
+        WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+        List<WifiConfiguration> configs = wifiManager.getConfiguredNetworks();
+        if (configs == null) {
+            return null;
+        }
+
+        WifiConfiguration config;
+        for (int i = 0; i < configs.size(); i++) {
+            config = configs.get(i);
+            if (TextUtils.equals(ssid, config.SSID)) {
+                return config;
+            }
+        }
+        return null;
+    }
+}
diff --git a/src/com/android/networkrecommendation/scoring/util/Util.java b/src/com/android/networkrecommendation/scoring/util/Util.java
new file mode 100644
index 0000000..4a8c80b
--- /dev/null
+++ b/src/com/android/networkrecommendation/scoring/util/Util.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2017 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.networkrecommendation.scoring.util;
+
+import static com.android.networkrecommendation.Constants.TAG;
+
+import android.content.Context;
+import android.net.NetworkScoreManager;
+import android.net.ScoredNetwork;
+import com.android.networkrecommendation.util.Blog;
+
+/** Utility methods for the scorer. */
+public final class Util {
+
+    /** @return true if GmsCore is the active network scorer. */
+    public static boolean isScorerActive(Context context) {
+        NetworkScoreManager scoreManager =
+                (NetworkScoreManager) context.getSystemService(Context.NETWORK_SCORE_SERVICE);
+        final String activeScorer = scoreManager.getActiveScorerPackage();
+        final String packageName = context.getPackageName();
+
+        return packageName.equals(activeScorer);
+    }
+
+    /** Clear scores in the platform if we're the active scorer. */
+    public static boolean safelyClearScores(Context context) {
+        try {
+            NetworkScoreManager scoreManager =
+                    (NetworkScoreManager) context.getSystemService(Context.NETWORK_SCORE_SERVICE);
+            scoreManager.clearScores();
+            return true;
+        } catch (SecurityException e) {
+            Blog.v(
+                    TAG,
+                    e,
+                    "SecurityException trying to clear scores, probably just an unavoidable race condition. "
+                            + "Ignoring.");
+            return false;
+        }
+    }
+
+    /** Update scores in the platform if we're the active scorer. */
+    public static boolean safelyUpdateScores(Context context, ScoredNetwork[] networkScores) {
+        try {
+            NetworkScoreManager scoreManager =
+                    (NetworkScoreManager) context.getSystemService(Context.NETWORK_SCORE_SERVICE);
+            scoreManager.updateScores(networkScores);
+            return true;
+        } catch (SecurityException e) {
+            Blog.v(
+                    TAG,
+                    e,
+                    "SecurityException trying to update scores, probably just an unavoidable race condition. "
+                            + "Ignoring.");
+            return false;
+        }
+    }
+}
diff --git a/src/com/android/networkrecommendation/util/Blog.java b/src/com/android/networkrecommendation/util/Blog.java
new file mode 100644
index 0000000..47eff57
--- /dev/null
+++ b/src/com/android/networkrecommendation/util/Blog.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2017 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.networkrecommendation.util;
+
+import android.text.TextUtils;
+import android.util.Base64;
+import android.util.Log;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import java.util.IllegalFormatException;
+import java.util.Locale;
+
+/**
+ * Wrapper for {@link Log} which adds the calling class/method to logged items.
+ *
+ * This works by traversing up the call stack and finding the first calling class whose name does
+ * not end with "Log" (allowing clients to add another layer such as AppLog when a constant tag is
+ * desired across the application).
+ */
+public final class Blog {
+    private static final String TAG = "Blog";
+
+    private Blog() {}
+
+    public static void i(String tag, String format, Object... args) {
+        Log.i(tag, buildMessage(format, args));
+    }
+
+    public static void i(String tag, Throwable tr, String format, Object... args) {
+        Log.i(tag, buildMessage(format, args), tr);
+    }
+
+    public static void v(String tag, String format, Object... args) {
+        // Not guarded with Log.isLoggable - these calls should be stripped out by proguard for
+        // release builds.
+        Log.v(tag, buildMessage(format, args));
+    }
+
+    public static void v(String tag, Throwable tr, String format, Object... args) {
+        // Not guarded with Log.isLoggable - these calls should be stripped out by proguard for
+        // release builds.
+        Log.v(tag, buildMessage(format, args), tr);
+    }
+
+    public static void d(String tag, String format, Object... args) {
+        if (Log.isLoggable(tag, Log.DEBUG)) {
+            Log.d(tag, buildMessage(format, args));
+        }
+    }
+
+    public static void d(String tag, Throwable tr, String format, Object... args) {
+        if (Log.isLoggable(tag, Log.DEBUG)) {
+            Log.d(tag, buildMessage(format, args), tr);
+        }
+    }
+
+    public static void w(String tag, Throwable tr, String format, Object... args) {
+        Log.w(tag, buildMessage(format, args), tr);
+    }
+
+    public static void w(String tag, String format, Object... args) {
+        Log.w(tag, buildMessage(format, args));
+    }
+
+    public static void e(String tag, String format, Object... args) {
+        Log.e(tag, buildMessage(format, args));
+    }
+
+    public static void e(String tag, Throwable tr, String format, Object... args) {
+        Log.e(tag, buildMessage(format, args), tr);
+    }
+
+    public static void wtf(String tag, String format, Object... args) {
+        // Ensure we always log a stack trace when calling Log.wtf.
+        Log.wtf(tag, buildMessage(format, args), new WhatATerribleException());
+    }
+
+    public static void wtf(String tag, Throwable tr, String format, Object...args) {
+        Log.wtf(tag, buildMessage(format, args), new WhatATerribleException(tr));
+    }
+
+    /**
+     * Redact personally identifiable information for production users.
+     *
+     * If:
+     *     1) String is null
+     *     2) String is empty
+     *     3) enableSensitiveLogging param passed in is true
+     *   Return the String value of the input object.
+     * Else:
+     *   Return a SHA-1 hash of the String value of the input object.
+     */
+    public static String pii(Object pii, boolean enableSensitiveLogging) {
+        String val = String.valueOf(pii);
+        if (pii == null || TextUtils.isEmpty(val) || enableSensitiveLogging) {
+            return val;
+        }
+        return "[" + secureHash(val.getBytes()) + "]";
+    }
+
+    /**
+     * Returns a secure hash (using the SHA1 algorithm) of the provided input.
+     *
+     * @return the hash
+     * @param input the bytes for which the secure hash should be computed.
+     */
+    public static String secureHash(byte[] input) {
+        MessageDigest messageDigest;
+        try {
+            messageDigest = MessageDigest.getInstance("SHA-1");
+        } catch (NoSuchAlgorithmException e) {
+            return null;
+        }
+        messageDigest.update(input);
+        byte[] result = messageDigest.digest();
+        return Base64.encodeToString(
+                result, Base64.URL_SAFE | Base64.NO_PADDING | Base64.NO_WRAP);
+    }
+
+    /**
+     * Formats the caller's provided message and prepends useful info like
+     * calling thread ID and method name.
+     */
+    private static String buildMessage(String format, Object... args) {
+        String msg;
+        try {
+            msg = (args == null || args.length == 0) ? format
+                    : String.format(Locale.US, format, args);
+        } catch (IllegalFormatException ife) {
+            String formattedArgs = Arrays.toString(args);
+            wtf(TAG, ife, "msg: \"%s\" args: %s", format, formattedArgs);
+            msg = format + " " + formattedArgs;
+        }
+        StackTraceElement[] trace = new Throwable().fillInStackTrace().getStackTrace();
+        String caller = "<unknown>";
+        // Walk up the stack looking for the first caller outside of Blog whose name doesn't end
+        // with "Log". It will be at least two frames up, so start there.
+        for (int i = 2; i < trace.length; i++) {
+            String callingClass = trace[i].getClassName();
+            if (!callingClass.equals(Blog.class.getName())
+                        && !callingClass.endsWith("Log")) {
+                callingClass = callingClass.substring(callingClass.lastIndexOf('.') + 1);
+                callingClass = callingClass.substring(callingClass.lastIndexOf('$') + 1);
+                caller = callingClass + "." + trace[i].getMethodName();
+                break;
+            }
+        }
+        return String.format(Locale.US, "[%d] %s: %s",
+                Thread.currentThread().getId(), caller, msg);
+    }
+
+    /** Named exception thrown when calling wtf(). */
+    public static class WhatATerribleException extends RuntimeException {
+        public WhatATerribleException() {
+            super();
+        }
+        public WhatATerribleException(Throwable t) {
+            super(t);
+        }
+    }
+}
diff --git a/src/com/android/networkrecommendation/util/NotificationChannelUtil.java b/src/com/android/networkrecommendation/util/NotificationChannelUtil.java
new file mode 100644
index 0000000..ebe5ff3
--- /dev/null
+++ b/src/com/android/networkrecommendation/util/NotificationChannelUtil.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2017 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.networkrecommendation.util;
+
+import android.app.Notification.Builder;
+import android.app.NotificationChannel;
+import android.app.NotificationChannelGroup;
+import android.app.NotificationManager;
+import android.content.Context;
+import com.android.networkrecommendation.R;
+
+/**
+ * Util class for managing {@link android.app.NotificationChannel}s for our notifications.
+ * TODO(netrec): b/36486429 Add tests for this class once relevant class constructors are supported
+ * for Robolectric.
+ */
+public class NotificationChannelUtil {
+
+    private static final String CHANNEL_GROUP_ID =
+            "com.android.networkrecommendation.Notifications.WifiMessageGroup";
+    public static final String CHANNEL_ID_NETWORK_AVAILABLE =
+            "com.android.networkrecommendation.Notifications.WifiMessageGroup.NetworkAvailableChannel";
+    public static final String CHANNEL_ID_WAKEUP =
+            "com.android.networkrecommendation.Notifications.WifiMessageGroup.WakeupChannel";
+
+    /** Configures the {@link android.app.NotificationChannel}s for our module. */
+    public static void configureNotificationChannels(
+            NotificationManager notificationManager, Context context) {
+        NotificationChannelGroup notificationChannelGroup =
+                new NotificationChannelGroup(
+                        CHANNEL_GROUP_ID,
+                        context.getString(R.string.notification_channel_group_name));
+        notificationManager.createNotificationChannelGroup(notificationChannelGroup);
+
+        NotificationChannel networkAvailableChannel =
+                new NotificationChannel(
+                        CHANNEL_ID_NETWORK_AVAILABLE,
+                        context.getString(R.string.notification_channel_network_available),
+                        NotificationManager.IMPORTANCE_LOW);
+        networkAvailableChannel.setGroup(CHANNEL_GROUP_ID);
+        notificationManager.createNotificationChannel(networkAvailableChannel);
+
+        NotificationChannel wakeupChannel =
+                new NotificationChannel(
+                        CHANNEL_ID_WAKEUP,
+                        context.getString(R.string.notification_channel_wakeup_name),
+                        NotificationManager.IMPORTANCE_LOW);
+        wakeupChannel.setGroup(CHANNEL_GROUP_ID);
+        notificationManager.createNotificationChannel(wakeupChannel);
+    }
+
+    /** Wraps Notification.Builder.setChannel. */
+    public static Builder setChannel(Builder notificationBuilder, String channelId) {
+        return notificationBuilder.setChannelId(channelId);
+    }
+}
diff --git a/src/com/android/networkrecommendation/util/OCompatFactory.java b/src/com/android/networkrecommendation/util/OCompatFactory.java
new file mode 100644
index 0000000..ef949cf
--- /dev/null
+++ b/src/com/android/networkrecommendation/util/OCompatFactory.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2017 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.networkrecommendation.util;
+
+import android.net.NetworkKey;
+import android.net.RssiCurve;
+import android.net.ScoredNetwork;
+import android.os.Bundle;
+
+/**
+ * Encapsulates the constructors for O-only objects to make unit testing possible, since those APIs
+ * are not supported by Robolectric yet. Once Robolectric supports O, we can remove this class.
+ */
+public class OCompatFactory {
+
+    /** Create a ScoredNetwork with the provided parameters. */
+    public static ScoredNetwork createScoredNetworkOCompat(
+            NetworkKey networkToScore,
+            RssiCurve rssiCurve,
+            boolean meteredHint,
+            Bundle attributesBundle) {
+        return new ScoredNetwork(networkToScore, rssiCurve, meteredHint, attributesBundle);
+    }
+
+    /** Create an RssiCurve with the provided parameters. */
+    public static RssiCurve createRssiCurveOCompat(
+            int start, int bucketWidth, byte[] rssiBuckets, int activeNetworkRssiBoost) {
+        return new RssiCurve(start, bucketWidth, rssiBuckets, activeNetworkRssiBoost);
+    }
+}
diff --git a/src/com/android/networkrecommendation/util/RoboCompatUtil.java b/src/com/android/networkrecommendation/util/RoboCompatUtil.java
new file mode 100644
index 0000000..7aa0d7b
--- /dev/null
+++ b/src/com/android/networkrecommendation/util/RoboCompatUtil.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2017 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.networkrecommendation.util;
+
+import android.content.res.Resources.Theme;
+import android.graphics.drawable.Drawable;
+import android.net.NetworkBadging;
+import android.net.RssiCurve;
+import android.net.ScoredNetwork;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
+import android.os.Bundle;
+import android.os.UserManager;
+import android.support.annotation.VisibleForTesting;
+
+/**
+ * This class provides access to @SystemApi methods that were added in Android O and not yet
+ * available in using the --config robo_experimental configuration when testing.
+ */
+public class RoboCompatUtil {
+
+    /**
+     * {@link UserManager#ACTION_USER_RESTRICTIONS_CHANGED}. TODO: remove when string is available
+     * in experimental.
+     */
+    public static final String ACTION_USER_RESTRICTIONS_CHANGED =
+            "android.os.action.USER_RESTRICTIONS_CHANGED";
+
+    private static RoboCompatUtil mRoboCompatUtil;
+
+    private RoboCompatUtil() {}
+
+    /** Get a shared instance of this utility. */
+    public static synchronized RoboCompatUtil getInstance() {
+        if (mRoboCompatUtil == null) {
+            mRoboCompatUtil = new RoboCompatUtil();
+        }
+        return mRoboCompatUtil;
+    }
+
+    @VisibleForTesting
+    public static void setInstanceForTesting(RoboCompatUtil roboCompatUtil) {
+        mRoboCompatUtil = roboCompatUtil;
+    }
+
+    /** Wraps WifiManager.connect. */
+    public void connectToWifi(WifiManager wifiManager, WifiConfiguration wifiConfiguration) {
+        wifiManager.connect(wifiConfiguration, null /* actionListener */);
+    }
+
+    /** Wraps WifiConfiguration.hasNoInternetAccess. */
+    @SuppressWarnings("unchecked")
+    public boolean hasNoInternetAccess(WifiConfiguration wifiConfiguration) {
+        return wifiConfiguration.hasNoInternetAccess();
+    }
+
+    /** Wraps WifiConfiguration.isNoInternetAccessExpected. */
+    public boolean isNoInternetAccessExpected(WifiConfiguration wifiConfiguration) {
+        return wifiConfiguration.isNoInternetAccessExpected();
+    }
+
+    /** Wraps WifiConfiguration.useExternalScores. */
+    public boolean useExternalScores(WifiConfiguration wifiConfiguration) {
+        return wifiConfiguration.useExternalScores;
+    }
+
+    /** Wraps WifiConfiguration.isPasspoint. */
+    public boolean isPasspoint(WifiConfiguration wifiConfiguration) {
+        return wifiConfiguration.isPasspoint();
+    }
+
+    /** Wraps NetworkBadging.getWifiIcon. */
+    public Drawable getWifiIcon(int signalLevel, int badging, Theme theme) {
+        return NetworkBadging.getWifiIcon(signalLevel, badging, theme);
+    }
+
+    /** Wraps RssiCurve.activeNetworkRssiBoost. */
+    public int activeNetworkRssiBoost(RssiCurve curve) {
+        return curve.activeNetworkRssiBoost;
+    }
+
+    /** Wraps ScoredNetwork.attributes. */
+    public Bundle attributes(ScoredNetwork scoredNetwork) {
+        return scoredNetwork.attributes;
+    }
+}
diff --git a/src/com/android/networkrecommendation/ScanResultUtil.java b/src/com/android/networkrecommendation/util/ScanResultUtil.java
similarity index 64%
rename from src/com/android/networkrecommendation/ScanResultUtil.java
rename to src/com/android/networkrecommendation/util/ScanResultUtil.java
index 08b71d0..4587e91 100644
--- a/src/com/android/networkrecommendation/ScanResultUtil.java
+++ b/src/com/android/networkrecommendation/util/ScanResultUtil.java
@@ -13,39 +13,44 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package com.android.networkrecommendation.util;
 
-package com.android.networkrecommendation;
+import static com.android.networkrecommendation.Constants.TAG;
+import static com.android.networkrecommendation.util.SsidUtil.quoteSsid;
 
+import android.net.NetworkKey;
+import android.net.WifiKey;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration;
-import android.support.annotation.VisibleForTesting;
+import android.support.annotation.Nullable;
 import android.text.TextUtils;
+import com.android.networkrecommendation.config.G;
 
 /**
- * Scan result utility for any {@link ScanResult} related operations.
- * TODO(b/34125341): Delete this class once exposed as a SystemApi
+ * Scan result utility for any {@link ScanResult} related operations. TODO(b/34125341): Delete this
+ * class once exposed as a SystemApi
  */
 public class ScanResultUtil {
 
     /**
-     * Helper method to check if the provided |scanResult| corresponds to a PSK network or not.
-     * This checks if the provided capabilities string contains PSK encryption type or not.
+     * Helper method to check if the provided |scanResult| corresponds to a PSK network or not. This
+     * checks if the provided capabilities string contains PSK encryption type or not.
      */
     public static boolean isScanResultForPskNetwork(ScanResult scanResult) {
         return scanResult.capabilities.contains("PSK");
     }
 
     /**
-     * Helper method to check if the provided |scanResult| corresponds to a EAP network or not.
-     * This checks if the provided capabilities string contains EAP encryption type or not.
+     * Helper method to check if the provided |scanResult| corresponds to a EAP network or not. This
+     * checks if the provided capabilities string contains EAP encryption type or not.
      */
     public static boolean isScanResultForEapNetwork(ScanResult scanResult) {
         return scanResult.capabilities.contains("EAP");
     }
 
     /**
-     * Helper method to check if the provided |scanResult| corresponds to a WEP network or not.
-     * This checks if the provided capabilities string contains WEP encryption type or not.
+     * Helper method to check if the provided |scanResult| corresponds to a WEP network or not. This
+     * checks if the provided capabilities string contains WEP encryption type or not.
      */
     public static boolean isScanResultForWepNetwork(ScanResult scanResult) {
         return scanResult.capabilities.contains("WEP");
@@ -57,17 +62,43 @@
      * encryption types or not.
      */
     public static boolean isScanResultForOpenNetwork(ScanResult scanResult) {
-        return !(isScanResultForWepNetwork(scanResult) || isScanResultForPskNetwork(scanResult)
+        return !(isScanResultForWepNetwork(scanResult)
+                || isScanResultForPskNetwork(scanResult)
                 || isScanResultForEapNetwork(scanResult));
     }
 
+    /** Create a {@link NetworkKey} from a ScanResult, properly quoting the SSID. */
+    @Nullable
+    public static final NetworkKey createNetworkKey(ScanResult scanResult) {
+        WifiKey wifiKey = createWifiKey(scanResult);
+        if (wifiKey == null) {
+            return null;
+        }
+        return new NetworkKey(wifiKey);
+    }
+
     /**
      * Helper method to quote the SSID in Scan result to use for comparing/filling SSID stored in
      * WifiConfiguration object.
      */
-    @VisibleForTesting
-    public static String createQuotedSSID(String ssid) {
-        return "\"" + ssid + "\"";
+    @Nullable
+    public static WifiKey createWifiKey(ScanResult result) {
+        if (result == null) {
+            Blog.e(TAG, "Couldn't create WifiKey, provided scan result is null.");
+            return null;
+        }
+        try {
+            return new WifiKey(quoteSsid(result.SSID), result.BSSID);
+        } catch (IllegalArgumentException | NullPointerException e) {
+            // Expect IllegalArgumentException only in Android O.
+            Blog.e(
+                    TAG,
+                    e,
+                    "Couldn't make a wifi key from %s/%s",
+                    Blog.pii(result.SSID, G.Netrec.enableSensitiveLogging.get()),
+                    Blog.pii(result.BSSID, G.Netrec.enableSensitiveLogging.get()));
+            return null;
+        }
     }
 
     /** @return {@code true} if the result is for a 2.4GHz network. */
@@ -91,13 +122,13 @@
     }
 
     /**
-     * Checks if the provided |scanResult| match with the provided |config|. Essentially checks
-     * if the network config and scan result have the same SSID and encryption type.
+     * Checks if the provided |scanResult| match with the provided |config|. Essentially checks if
+     * the network config and scan result have the same SSID and encryption type.
      */
     public static boolean doesScanResultMatchWithNetwork(
             ScanResult scanResult, WifiConfiguration config) {
         // Add the double quotes to the scan result SSID for comparison with the network configs.
-        String configSSID = createQuotedSSID(scanResult.SSID);
+        String configSSID = quoteSsid(scanResult.SSID);
         if (TextUtils.equals(config.SSID, configSSID)) {
             if (ScanResultUtil.isScanResultForPskNetwork(scanResult)
                     && WifiConfigurationUtil.isConfigForPskNetwork(config)) {
diff --git a/src/com/android/networkrecommendation/util/SsidUtil.java b/src/com/android/networkrecommendation/util/SsidUtil.java
new file mode 100644
index 0000000..b15ac5f
--- /dev/null
+++ b/src/com/android/networkrecommendation/util/SsidUtil.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2017 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.networkrecommendation.util;
+
+import static com.android.networkrecommendation.Constants.TAG;
+
+import android.net.WifiKey;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+import com.android.networkrecommendation.config.G;
+
+/** Utility methods for Wifi Network SSID and BSSID manipulation. */
+public final class SsidUtil {
+
+    // A special BSSID used to indicate a wildcard/ignore.
+    // The MAC address this refers to is reserved by IANA
+    // http://www.iana.org/assignments/ethernet-numbers/ethernet-numbers.xhtml
+    public static final String BSSID_IGNORE = "00:00:5E:00:00:00";
+
+    /** Quote an SSID if it hasn't already been quoted. */
+    @Nullable
+    public static String quoteSsid(@Nullable String ssid) {
+        if (ssid == null) {
+            return null;
+        }
+        if (isValidQuotedSsid(ssid)) {
+            return ssid;
+        }
+        return "\"" + ssid + "\"";
+    }
+
+    /** Strip initial and final quotations marks from an SSID. */
+    public static String unquoteSsid(@Nullable String ssid) {
+        if (ssid == null) {
+            return null;
+        }
+        return ssid.replaceAll("^\"", "").replaceAll("\"$", "");
+    }
+
+    /**
+     * Create a WifiKey for the given SSID/BSSID. Returns null if the key could not be created
+     * (ssid/bssid are not valid patterns).
+     */
+    @Nullable
+    public static WifiKey createWifiKey(String ssid, String bssid) {
+        try {
+            return new WifiKey(quoteSsid(ssid), bssid);
+        } catch (IllegalArgumentException | NullPointerException e) {
+            // Expect IllegalArgumentException only in Android O.
+            Blog.e(
+                    TAG,
+                    e,
+                    "Couldn't make a wifi key from %s/%s",
+                    Blog.pii(ssid, G.Netrec.enableSensitiveLogging.get()),
+                    Blog.pii(bssid, G.Netrec.enableSensitiveLogging.get()));
+            return null;
+        }
+    }
+
+    /**
+     * Returns true if the given string will be accepted as an SSID by WifiKey, especially meaning
+     * it is quoted.
+     */
+    public static boolean isValidQuotedSsid(@Nullable String ssid) {
+        return ssid != null && ssid.startsWith("\"") && ssid.endsWith("\"");
+    }
+
+    /** Thows IllegalArgumentException if the given string cannot be used for an SSID in WifiKey. */
+    public static void checkIsValidQuotedSsid(String ssid) {
+        if (!isValidQuotedSsid(ssid)) {
+            throw new IllegalArgumentException("SSID " + ssid + " expected to be quoted");
+        }
+    }
+
+    /**
+     * Returns true if the canonical version of two SSIDs (ignoring wrapping quotations) is equal.
+     */
+    public static boolean areEqual(@Nullable String ssid1, @Nullable String ssid2) {
+        String quotedSsid1 = quoteSsid(ssid1);
+        String quotedSsid2 = quoteSsid(ssid2);
+        return TextUtils.equals(quotedSsid1, quotedSsid2);
+    }
+
+    /**
+     * Returns a string version of the SSID for logging which is typically redacted.
+     *
+     * <p>The ID will only be returned verbatim if the enableSensitiveLogging flag is set.
+     */
+    public static String getRedactedId(String ssid) {
+        return Blog.pii(String.format("%s", ssid), G.Netrec.enableSensitiveLogging.get());
+    }
+
+    /**
+     * Returns a string version of the SSID/BSSID pair for logging which is typically redacted.
+     *
+     * <p>The IDs will only be returned verbatim if the enableSensitiveLogging flag is set.
+     */
+    public static String getRedactedId(String ssid, String bssid) {
+        return Blog.pii(String.format("%s/%s", ssid, bssid), G.Netrec.enableSensitiveLogging.get());
+    }
+
+    // Can't instantiate.
+    private SsidUtil() {}
+}
diff --git a/src/com/android/networkrecommendation/WifiConfigurationUtil.java b/src/com/android/networkrecommendation/util/WifiConfigurationUtil.java
similarity index 98%
rename from src/com/android/networkrecommendation/WifiConfigurationUtil.java
rename to src/com/android/networkrecommendation/util/WifiConfigurationUtil.java
index d653a4f..3616cd7 100644
--- a/src/com/android/networkrecommendation/WifiConfigurationUtil.java
+++ b/src/com/android/networkrecommendation/util/WifiConfigurationUtil.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.networkrecommendation;
+package com.android.networkrecommendation.util;
 
 import android.net.wifi.WifiConfiguration;
 
diff --git a/src/com/android/networkrecommendation/wakeup/WifiWakeupController.java b/src/com/android/networkrecommendation/wakeup/WifiWakeupController.java
new file mode 100644
index 0000000..4c9b4c1
--- /dev/null
+++ b/src/com/android/networkrecommendation/wakeup/WifiWakeupController.java
@@ -0,0 +1,404 @@
+/*
+ * Copyright (C) 2017 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.networkrecommendation.wakeup;
+
+import static com.android.networkrecommendation.Constants.TAG;
+
+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.wifi.ScanResult;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+import android.os.PowerManager;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.support.annotation.VisibleForTesting;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import com.android.networkrecommendation.config.G;
+import com.android.networkrecommendation.config.Preferences;
+import com.android.networkrecommendation.config.WideAreaNetworks;
+import com.android.networkrecommendation.scoring.util.HashUtil;
+import com.android.networkrecommendation.util.Blog;
+import com.android.networkrecommendation.util.RoboCompatUtil;
+import com.android.networkrecommendation.util.WifiConfigurationUtil;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Handles enabling Wi-Fi for the Wi-Fi Wakeup feature.
+ *
+ * <p>This class enables Wi-Fi when the user is near a network that would would autojoined if Wi-Fi
+ * were enabled. When a user disables Wi-Fi, Wi-Fi Wakeup will not enable Wi-Fi until the user's
+ * context has changed. For saved networks, this context change is defined by the user leaving the
+ * range of the saved SSIDs that were in range when the user disabled Wi-Fi.
+ *
+ * @hide
+ */
+public class WifiWakeupController {
+    /** Number of scans to ensure that a previously in range AP is now out of range. */
+    private static final int NUM_SCANS_TO_CONFIRM_AP_LOSS = 3;
+
+    private final Context mContext;
+    private final ContentResolver mContentResolver;
+    private final WifiManager mWifiManager;
+    private final PowerManager mPowerManager;
+    private final UserManager mUserManager;
+    private final WifiWakeupNetworkSelector mWifiWakeupNetworkSelector;
+    private final Handler mHandler;
+    private final WifiWakeupHelper mWifiWakeupHelper;
+    private final AtomicBoolean mStarted;
+    @VisibleForTesting final ContentObserver mContentObserver;
+
+    private final Map<String, WifiConfiguration> mSavedNetworks = new ArrayMap<>();
+    private final Set<String> mSavedSsidsInLastScan = new ArraySet<>();
+    private final Set<String> mSavedSsids = new ArraySet<>();
+    private final Map<String, Integer> mSavedSsidsOnDisable = new ArrayMap<>();
+    private final SavedNetworkCounts mSavedNetworkCounts = new SavedNetworkCounts();
+    private int mWifiState;
+    private int mWifiApState;
+    private boolean mWifiWakeupEnabled;
+    private boolean mAirplaneModeEnabled;
+    private boolean mAutopilotEnabledWifi;
+    private boolean mPowerSaverModeOn;
+    private boolean mWifiConfigRestricted;
+
+    public WifiWakeupController(
+            Context context,
+            ContentResolver contentResolver,
+            Handler handler,
+            WifiManager wifiManager,
+            PowerManager powerManager,
+            UserManager userManager,
+            WifiWakeupNetworkSelector wifiWakeupNetworkSelector,
+            WifiWakeupHelper wifiWakeupHelper) {
+        mContext = context;
+        mContentResolver = contentResolver;
+        mHandler = handler;
+        mWifiWakeupHelper = wifiWakeupHelper;
+        mStarted = new AtomicBoolean(false);
+        mWifiManager = wifiManager;
+        mPowerManager = powerManager;
+        mUserManager = userManager;
+        mWifiWakeupNetworkSelector = wifiWakeupNetworkSelector;
+        mContentObserver =
+                new ContentObserver(mHandler) {
+                    @Override
+                    public void onChange(boolean selfChange) {
+                        mWifiWakeupEnabled =
+                                Settings.Global.getInt(
+                                                mContentResolver,
+                                                Settings.Global.WIFI_WAKEUP_ENABLED,
+                                                0)
+                                        == 1;
+                        mAirplaneModeEnabled =
+                                Settings.Global.getInt(
+                                                mContentResolver,
+                                                Settings.Global.AIRPLANE_MODE_ON,
+                                                0)
+                                        == 1;
+                        Blog.d(
+                                TAG,
+                                "onChange: [mWifiWakeupEnabled=%b,mAirplaneModeEnabled=%b]",
+                                mWifiWakeupEnabled,
+                                mAirplaneModeEnabled);
+                    }
+                };
+    }
+
+    private final BroadcastReceiver mBroadcastReceiver =
+            new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    try {
+                        if (WifiManager.WIFI_AP_STATE_CHANGED_ACTION.equals(intent.getAction())) {
+                            handleWifiApStateChanged();
+                        } else if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(
+                                intent.getAction())) {
+                            handleWifiStateChanged(false);
+                        } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(
+                                intent.getAction())) {
+                            handleScanResultsAvailable();
+                        } else if (WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION.equals(
+                                intent.getAction())) {
+                            handleConfiguredNetworksChanged();
+                        } else if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals(
+                                intent.getAction())) {
+                            handlePowerSaverModeChanged();
+                        } else if (RoboCompatUtil.ACTION_USER_RESTRICTIONS_CHANGED.equals(
+                                intent.getAction())) {
+                            handleUserRestrictionsChanged();
+                        }
+                    } catch (RuntimeException re) {
+                        // TODO(b/35044022) Remove try/catch after a couple of releases when we are confident
+                        // this is not going to throw.
+                        Blog.e(TAG, re, "RuntimeException in broadcast receiver.");
+                    }
+                }
+            };
+
+    /** Starts {@link WifiWakeupController}. */
+    public void start() {
+        if (!mStarted.compareAndSet(false, true)) {
+            return;
+        }
+        Blog.d(TAG, "Starting WifiWakeupController.");
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
+        filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
+        filter.addAction(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION);
+        filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
+        filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
+        filter.addAction(RoboCompatUtil.ACTION_USER_RESTRICTIONS_CHANGED);
+        // TODO(b/33695273): conditionally register this receiver based on wifi enabled setting
+        mContext.registerReceiver(mBroadcastReceiver, filter, null, mHandler);
+        mContentResolver.registerContentObserver(
+                Settings.Global.getUriFor(Settings.Global.WIFI_WAKEUP_ENABLED),
+                true,
+                mContentObserver);
+        mContentResolver.registerContentObserver(
+                Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON),
+                true,
+                mContentObserver);
+        mContentObserver.onChange(true);
+        handlePowerSaverModeChanged();
+        handleUserRestrictionsChanged();
+        handleWifiApStateChanged();
+        handleConfiguredNetworksChanged();
+        handleWifiStateChanged(true);
+        handleScanResultsAvailable();
+    }
+
+    /** Stops {@link WifiWakeupController}. */
+    public void stop() {
+        if (!mStarted.compareAndSet(true, false)) {
+            return;
+        }
+        Blog.d(TAG, "Stopping WifiWakeupController.");
+        mContext.unregisterReceiver(mBroadcastReceiver);
+        mContentResolver.unregisterContentObserver(mContentObserver);
+    }
+
+    private void handlePowerSaverModeChanged() {
+        mPowerSaverModeOn = mPowerManager.isPowerSaveMode();
+        Blog.v(TAG, "handlePowerSaverModeChanged: %b", mPowerSaverModeOn);
+    }
+
+    private void handleWifiApStateChanged() {
+        mWifiApState = mWifiManager.getWifiApState();
+        Blog.v(TAG, "handleWifiApStateChanged: %d", mWifiApState);
+    }
+
+    private void handleUserRestrictionsChanged() {
+        mWifiConfigRestricted = mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_WIFI);
+        Blog.v(TAG, "handleUserRestrictionsChanged: %b", mWifiConfigRestricted);
+    }
+
+    private void handleConfiguredNetworksChanged() {
+        List<WifiConfiguration> wifiConfigurations = mWifiManager.getConfiguredNetworks();
+        if (wifiConfigurations == null) {
+            return;
+        }
+        Blog.v(TAG, "handleConfiguredNetworksChanged: %d", wifiConfigurations.size());
+
+        mSavedNetworkCounts.clear();
+        mSavedNetworkCounts.total = wifiConfigurations.size();
+        mSavedNetworks.clear();
+        mSavedSsids.clear();
+        for (int i = 0; i < wifiConfigurations.size(); i++) {
+            WifiConfiguration wifiConfiguration = wifiConfigurations.get(i);
+            if (wifiConfiguration.status != WifiConfiguration.Status.ENABLED
+                    && wifiConfiguration.status != WifiConfiguration.Status.CURRENT) {
+                continue; // Ignore networks that are not connected or enabled.
+            }
+            mSavedNetworkCounts.enabled++;
+            if (RoboCompatUtil.getInstance().hasNoInternetAccess(wifiConfiguration)) {
+                mSavedNetworkCounts.noInternetAccess++;
+                continue; // Ignore networks that do not have verified internet access.
+            }
+            if (RoboCompatUtil.getInstance().isNoInternetAccessExpected(wifiConfiguration)) {
+                mSavedNetworkCounts.noInternetAccessExpected++;
+                continue; // Ignore networks that are expected not to have internet access.
+            }
+            String ssid = WifiConfigurationUtil.removeDoubleQuotes(wifiConfiguration);
+            if (TextUtils.isEmpty(ssid)) {
+                continue;
+            }
+            if (WideAreaNetworks.contains(ssid)) {
+                mSavedNetworkCounts.blacklisted++;
+                continue; // Ignore wide area networks.
+            }
+            mSavedNetworks.put(ssid, wifiConfiguration);
+            mSavedSsids.add(ssid);
+
+            if (WifiConfigurationUtil.isConfigForOpenNetwork(wifiConfiguration)) {
+                mSavedNetworkCounts.open++;
+            }
+            if (RoboCompatUtil.getInstance().useExternalScores(wifiConfiguration)) {
+                mSavedNetworkCounts.useExternalScores++;
+            }
+        }
+        mSavedSsidsInLastScan.retainAll(mSavedSsids);
+    }
+
+    private void handleWifiStateChanged(boolean calledOnStart) {
+        mWifiState = mWifiManager.getWifiState();
+        Blog.v(TAG, "handleWifiStateChanged: %d", mWifiState);
+
+        switch (mWifiState) {
+            case WifiManager.WIFI_STATE_ENABLED:
+                mSavedSsidsOnDisable.clear();
+                if (!mAutopilotEnabledWifi) {}
+                break;
+            case WifiManager.WIFI_STATE_DISABLED:
+                if (calledOnStart) {
+                    readDisabledSsidsFromSharedPreferences();
+                } else {
+                    for (String ssid : mSavedSsidsInLastScan) {
+                        mSavedSsidsOnDisable.put(ssid, NUM_SCANS_TO_CONFIRM_AP_LOSS);
+                    }
+                    writeDisabledSsidsToSharedPreferences();
+                }
+                Blog.d(TAG, "Disabled ssid set: %s", mSavedSsidsOnDisable);
+
+                mAutopilotEnabledWifi = false;
+                break;
+            default: // Only handle ENABLED and DISABLED states
+        }
+    }
+
+    private void readDisabledSsidsFromSharedPreferences() {
+        Set<String> ssidsOnDisable = Preferences.savedSsidsOnDisable.get();
+        for (String ssid : mSavedSsids) {
+            if (ssidsOnDisable.contains(HashUtil.getSsidHash(ssid))) {
+                mSavedSsidsOnDisable.put(ssid, NUM_SCANS_TO_CONFIRM_AP_LOSS);
+            }
+        }
+    }
+
+    private void writeDisabledSsidsToSharedPreferences() {
+        Set<String> ssids = new ArraySet<>();
+        for (String ssid : mSavedSsidsOnDisable.keySet()) {
+            ssids.add(HashUtil.getSsidHash(ssid));
+        }
+        Preferences.savedSsidsOnDisable.put(ssids);
+    }
+
+    private void handleScanResultsAvailable() {
+        if (!mWifiWakeupEnabled || mWifiConfigRestricted) {
+            return;
+        }
+        List<ScanResult> scanResults = mWifiManager.getScanResults();
+        if (scanResults == null) {
+            return;
+        }
+        Blog.v(TAG, "handleScanResultsAvailable: %d", scanResults.size());
+
+        mSavedSsidsInLastScan.clear();
+        for (int i = 0; i < scanResults.size(); i++) {
+            String ssid = scanResults.get(i).SSID;
+            if (mSavedSsids.contains(ssid)) {
+                mSavedSsidsInLastScan.add(ssid);
+            }
+        }
+
+        if (mAirplaneModeEnabled
+                || mWifiState != WifiManager.WIFI_STATE_DISABLED
+                || mWifiApState != WifiManager.WIFI_AP_STATE_DISABLED
+                || mPowerSaverModeOn) {
+            return;
+        }
+
+        // Update mSavedSsidsOnDisable to remove ssids that the user has moved away from.
+        for (Map.Entry<String, Integer> entry : mSavedSsidsOnDisable.entrySet()) {
+            if (mSavedSsidsInLastScan.contains(entry.getKey())) {
+                mSavedSsidsOnDisable.put(entry.getKey(), NUM_SCANS_TO_CONFIRM_AP_LOSS);
+            } else {
+                if (entry.getValue() > 1) {
+                    mSavedSsidsOnDisable.put(entry.getKey(), entry.getValue() - 1);
+                } else {
+                    mSavedSsidsOnDisable.remove(entry.getKey());
+                }
+            }
+        }
+
+        if (!mSavedSsidsOnDisable.isEmpty()) {
+            Blog.d(
+                    TAG,
+                    "Scan results contain ssids from the disabled set: %s",
+                    mSavedSsidsOnDisable);
+            return;
+        }
+
+        if (mSavedSsidsInLastScan.isEmpty()) {
+            Blog.v(TAG, "Scan results do not contain any saved ssids.");
+            return;
+        }
+
+        WifiConfiguration selectedNetwork =
+                mWifiWakeupNetworkSelector.selectNetwork(mSavedNetworks, scanResults);
+        if (selectedNetwork != null) {
+            Blog.d(
+                    TAG,
+                    "Enabling wifi for ssid: %s",
+                    Blog.pii(selectedNetwork.SSID, G.Netrec.enableSensitiveLogging.get()));
+
+            mAutopilotEnabledWifi = true;
+            mWifiManager.setWifiEnabled(true /* enabled */);
+            mWifiWakeupHelper.startWifiSession(selectedNetwork);
+        }
+    }
+
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("mStarted " + mStarted.get());
+        pw.println("mWifiWakeupEnabled: " + mWifiWakeupEnabled);
+        pw.println("mSavedSsids: " + mSavedSsids);
+        pw.println("mSavedSsidsInLastScan: " + mSavedSsidsInLastScan);
+        pw.println("mSavedSsidsOnDisable: " + mSavedSsidsOnDisable);
+    }
+
+    /** Class to track counts for saved networks for logging. */
+    private static class SavedNetworkCounts {
+        int total;
+        int open;
+        int enabled;
+        int noInternetAccess;
+        int noInternetAccessExpected;
+        int useExternalScores;
+        int blacklisted;
+
+        void clear() {
+            total = 0;
+            open = 0;
+            enabled = 0;
+            noInternetAccess = 0;
+            noInternetAccessExpected = 0;
+            useExternalScores = 0;
+            blacklisted = 0;
+        }
+    }
+}
diff --git a/src/com/android/networkrecommendation/wakeup/WifiWakeupHelper.java b/src/com/android/networkrecommendation/wakeup/WifiWakeupHelper.java
new file mode 100644
index 0000000..8b4da55
--- /dev/null
+++ b/src/com/android/networkrecommendation/wakeup/WifiWakeupHelper.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2017 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.networkrecommendation.wakeup;
+
+import static com.android.networkrecommendation.Constants.TAG;
+import static com.android.networkrecommendation.util.NotificationChannelUtil.CHANNEL_ID_WAKEUP;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.provider.Settings;
+import android.support.annotation.NonNull;
+import android.support.annotation.VisibleForTesting;
+import android.text.TextUtils;
+import android.util.ArraySet;
+import com.android.networkrecommendation.R;
+import com.android.networkrecommendation.config.G;
+import com.android.networkrecommendation.config.Preferences;
+import com.android.networkrecommendation.scoring.util.HashUtil;
+import com.android.networkrecommendation.util.Blog;
+import com.android.networkrecommendation.util.NotificationChannelUtil;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Helper class for logging Wi-Fi Wakeup sessions and showing showing notifications for {@link
+ * WifiWakeupController}.
+ */
+public class WifiWakeupHelper {
+    /** Unique ID used for the Wi-Fi Enabled notification. */
+    private static final int NOTIFICATION_ID = R.string.wifi_wakeup_enabled_notification_title;
+
+    @VisibleForTesting
+    static final String ACTION_WIFI_SETTINGS =
+            "com.android.networkrecommendation.wakeup.ACTION_WIFI_SETTINGS";
+
+    @VisibleForTesting
+    static final String ACTION_DISMISS_WIFI_ENABLED_NOTIFICATION =
+            "com.android.networkrecommendation.wakeup.ACTION_DISMISS_WIFI_ENABLED_NOTIFICATION";
+
+    private static final long NETWORK_CONNECTED_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(30);
+    private static final IntentFilter INTENT_FILTER = new IntentFilter();
+
+    static {
+        INTENT_FILTER.addAction(ACTION_DISMISS_WIFI_ENABLED_NOTIFICATION);
+        INTENT_FILTER.addAction(ACTION_WIFI_SETTINGS);
+        INTENT_FILTER.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+    }
+
+    private final Context mContext;
+    private final Resources mResources;
+    private final NotificationManager mNotificationManager;
+    private final Handler mHandler;
+    private final WifiManager mWifiManager;
+
+    /** Whether the wakeup notification is currently displayed. */
+    private boolean mNotificationShown;
+    /** True when the device is still connected to the first connected ssid since wakeup. */
+    private boolean mWifiSessionStarted;
+    /** The first connected ssid after wakeup enabled wifi. */
+    private String mConnectedSsid;
+
+    private final BroadcastReceiver mBroadcastReceiver =
+            new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    try {
+                        if (ACTION_WIFI_SETTINGS.equals(intent.getAction())) {
+                            mContext.startActivity(
+                                    new Intent(Settings.ACTION_WIFI_SETTINGS)
+                                            .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+                        } else if (ACTION_DISMISS_WIFI_ENABLED_NOTIFICATION.equals(
+                                intent.getAction())) {
+                            cancelNotificationIfNeeded();
+                        } else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(
+                                intent.getAction())) {
+                            networkStateChanged();
+                        }
+                    } catch (RuntimeException re) {
+                        // TODO(b/35044022) Remove try/catch after a couple of releases when we are confident
+                        // this is not going to throw.
+                        Blog.e(TAG, re, "RuntimeException in broadcast receiver.");
+                    }
+                }
+            };
+
+    public WifiWakeupHelper(
+            Context context,
+            Resources resources,
+            Handler handler,
+            NotificationManager notificationManager,
+            WifiManager wifiManager) {
+        mContext = context;
+        mResources = resources;
+        mNotificationManager = notificationManager;
+        mHandler = handler;
+        mWifiManager = wifiManager;
+        mWifiSessionStarted = false;
+        mNotificationShown = false;
+        mConnectedSsid = null;
+    }
+
+    /**
+     * Start tracking a wifi wakeup session. Optionally show a notification that Wi-Fi has been
+     * enabled by Wi-Fi Wakeup if one has not been displayed for this {@link WifiConfiguration}.
+     *
+     * @param wifiConfiguration the {@link WifiConfiguration} that triggered Wi-Fi to wakeup
+     */
+    public void startWifiSession(@NonNull WifiConfiguration wifiConfiguration) {
+        mContext.registerReceiver(
+                mBroadcastReceiver, INTENT_FILTER, null /* broadcastPermission*/, mHandler);
+        mWifiSessionStarted = true;
+        mHandler.postDelayed(
+                () -> {
+                    if (mWifiSessionStarted && mConnectedSsid == null) {
+                        endWifiSession();
+                    }
+                },
+                NETWORK_CONNECTED_TIMEOUT_MILLIS);
+
+        Set<String> hashedSsidSet = Preferences.ssidsForWakeupShown.get();
+        String hashedSsid = HashUtil.getSsidHash(wifiConfiguration.SSID);
+        if (hashedSsidSet.isEmpty()) {
+            hashedSsidSet = new ArraySet<>();
+        } else if (hashedSsidSet.contains(hashedSsid)) {
+            Blog.i(
+                    TAG,
+                    "Already showed Wi-Fi Enabled notification for ssid: %s",
+                    Blog.pii(wifiConfiguration.SSID, G.Netrec.enableSensitiveLogging.get()));
+            return;
+        }
+        hashedSsidSet.add(hashedSsid);
+        Preferences.ssidsForWakeupShown.put(hashedSsidSet);
+
+        String title = mResources.getString(R.string.wifi_wakeup_enabled_notification_title);
+        String summary =
+                mResources.getString(
+                        R.string.wifi_wakeup_enabled_notification_context, wifiConfiguration.SSID);
+        PendingIntent savedNetworkSettingsPendingIntent =
+                PendingIntent.getBroadcast(
+                        mContext,
+                        0,
+                        new Intent(ACTION_WIFI_SETTINGS),
+                        PendingIntent.FLAG_UPDATE_CURRENT);
+        PendingIntent deletePendingIntent =
+                PendingIntent.getBroadcast(
+                        mContext,
+                        0,
+                        new Intent(ACTION_DISMISS_WIFI_ENABLED_NOTIFICATION),
+                        PendingIntent.FLAG_UPDATE_CURRENT);
+        Bundle extras = new Bundle();
+        extras.putString(
+                Notification.EXTRA_SUBSTITUTE_APP_NAME,
+                mResources.getString(R.string.notification_channel_group_name));
+        int smallIcon = R.drawable.ic_signal_wifi_statusbar_not_connected;
+        Notification.Builder notificationBuilder =
+                new Notification.Builder(mContext)
+                        .setContentTitle(title)
+                        .setSmallIcon(smallIcon)
+                        .setColor(mContext.getColor(R.color.color_tint))
+                        .setStyle(new Notification.BigTextStyle().bigText(summary))
+                        .setAutoCancel(true)
+                        .setShowWhen(false)
+                        .setDeleteIntent(deletePendingIntent)
+                        .setPriority(Notification.PRIORITY_LOW)
+                        .setVisibility(Notification.VISIBILITY_PUBLIC)
+                        .setCategory(Notification.CATEGORY_STATUS)
+                        .setContentIntent(savedNetworkSettingsPendingIntent)
+                        .setLocalOnly(true)
+                        .addExtras(extras);
+        NotificationChannelUtil.setChannel(notificationBuilder, CHANNEL_ID_WAKEUP);
+        mNotificationManager.notify(TAG, NOTIFICATION_ID, notificationBuilder.build());
+        mNotificationShown = true;
+    }
+
+    private void networkStateChanged() {
+        if (!mWifiManager.isWifiEnabled()) {
+            endWifiSession();
+            return;
+        }
+
+        WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
+        String ssid = wifiInfo == null ? null : wifiInfo.getSSID();
+        if (mConnectedSsid == null) {
+            if (!TextUtils.isEmpty(ssid)) {
+                mConnectedSsid = ssid;
+            }
+        } else if (!TextUtils.equals(ssid, mConnectedSsid)) {
+            endWifiSession();
+        }
+    }
+
+    private void endWifiSession() {
+        if (mWifiSessionStarted) {
+            mWifiSessionStarted = false;
+            cancelNotificationIfNeeded();
+            mConnectedSsid = null;
+            mContext.unregisterReceiver(mBroadcastReceiver);
+        }
+    }
+
+    private void cancelNotificationIfNeeded() {
+        if (mNotificationShown) {
+            mNotificationShown = false;
+            mNotificationManager.cancel(TAG, NOTIFICATION_ID);
+        }
+    }
+}
diff --git a/src/com/android/networkrecommendation/wakeup/WifiWakeupNetworkSelector.java b/src/com/android/networkrecommendation/wakeup/WifiWakeupNetworkSelector.java
new file mode 100644
index 0000000..61ed2cb
--- /dev/null
+++ b/src/com/android/networkrecommendation/wakeup/WifiWakeupNetworkSelector.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2017 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.networkrecommendation.wakeup;
+
+import android.content.res.Resources;
+import android.net.RecommendationRequest;
+import android.net.RecommendationResult;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiConfiguration;
+import android.support.annotation.Nullable;
+import android.util.ArraySet;
+import com.android.networkrecommendation.R;
+import com.android.networkrecommendation.SynchronousNetworkRecommendationProvider;
+import com.android.networkrecommendation.util.RoboCompatUtil;
+import com.android.networkrecommendation.util.ScanResultUtil;
+import com.android.networkrecommendation.util.WifiConfigurationUtil;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/** This class determines which network the framework would connect to if Wi-Fi was enabled. */
+public class WifiWakeupNetworkSelector {
+    private final int mThresholdQualifiedRssi24;
+    private final int mThresholdQualifiedRssi5;
+    private final int mRssiScoreSlope;
+    private final int mRssiScoreOffset;
+    private final int mPasspointSecurityAward;
+    private final int mSecurityAward;
+    private final int mBand5GHzAward;
+    private final int mThresholdSaturatedRssi24;
+    private final SynchronousNetworkRecommendationProvider mNetworkRecommendationProvider;
+
+    public WifiWakeupNetworkSelector(
+            Resources resources,
+            SynchronousNetworkRecommendationProvider networkRecommendationProvider) {
+        mThresholdQualifiedRssi24 =
+                resources.getInteger(R.integer.config_netrec_wifi_score_low_rssi_threshold_24GHz);
+        mThresholdQualifiedRssi5 =
+                resources.getInteger(R.integer.config_netrec_wifi_score_low_rssi_threshold_5GHz);
+        mRssiScoreSlope = resources.getInteger(R.integer.config_netrec_RSSI_SCORE_SLOPE);
+        mRssiScoreOffset = resources.getInteger(R.integer.config_netrec_RSSI_SCORE_OFFSET);
+        mPasspointSecurityAward =
+                resources.getInteger(R.integer.config_netrec_PASSPOINT_SECURITY_AWARD);
+        mSecurityAward = resources.getInteger(R.integer.config_netrec_SECURITY_AWARD);
+        mBand5GHzAward = resources.getInteger(R.integer.config_netrec_5GHz_preference_boost_factor);
+        mThresholdSaturatedRssi24 =
+                resources.getInteger(R.integer.config_netrec_wifi_score_good_rssi_threshold_24GHz);
+        mNetworkRecommendationProvider = networkRecommendationProvider;
+    }
+
+    /** Returns the network that the framework would most likely connect to if Wi-Fi was enabled. */
+    @Nullable
+    public WifiConfiguration selectNetwork(
+            Map<String, WifiConfiguration> savedNetworks, List<ScanResult> scanResults) {
+        Set<WifiConfiguration> openOrExternalConfigs = new ArraySet<>();
+        List<ScanResult> openOrExternalScanResults = new ArrayList<>();
+        WifiConfiguration candidateWifiConfiguration = null;
+        ScanResult candidateScanResult = null;
+        int candidateScore = -1;
+        for (int i = 0; i < scanResults.size(); i++) {
+            ScanResult scanResult = scanResults.get(i);
+            WifiConfiguration wifiConfiguration = savedNetworks.get(scanResult.SSID);
+            if (wifiConfiguration == null) {
+                continue;
+            }
+            if ((ScanResultUtil.is5GHz(scanResult) && scanResult.level < mThresholdQualifiedRssi5)
+                    || (ScanResultUtil.is24GHz(scanResult)
+                            && scanResult.level < mThresholdQualifiedRssi24)) {
+                continue;
+            }
+            if (!ScanResultUtil.doesScanResultMatchWithNetwork(scanResult, wifiConfiguration)) {
+                continue;
+            }
+            if (WifiConfigurationUtil.isConfigForOpenNetwork(wifiConfiguration)
+                    || RoboCompatUtil.getInstance().useExternalScores(wifiConfiguration)) {
+                // All open and externally scored networks should defer to network recommendations.
+                openOrExternalConfigs.add(wifiConfiguration);
+                openOrExternalScanResults.add(scanResult);
+                continue;
+            }
+            int score = calculateScore(scanResult, wifiConfiguration);
+            if (candidateScanResult == null
+                    || calculateScore(scanResult, wifiConfiguration) > candidateScore) {
+                candidateScanResult = scanResult;
+                candidateWifiConfiguration = wifiConfiguration;
+                candidateScore = score;
+            }
+        }
+        if (candidateWifiConfiguration == null && !openOrExternalConfigs.isEmpty()) {
+            // TODO(netrec): Add connectableConfigs after next SystemApi drop
+            RecommendationRequest request =
+                    new RecommendationRequest.Builder()
+                            .setScanResults(openOrExternalScanResults.toArray(new ScanResult[0]))
+                            .build();
+            RecommendationResult result =
+                    mNetworkRecommendationProvider.requestRecommendation(request);
+            return result.getWifiConfiguration();
+        }
+        return candidateWifiConfiguration;
+    }
+
+    private int calculateScore(ScanResult scanResult, WifiConfiguration wifiConfiguration) {
+        int score = 0;
+        // Calculate the RSSI score.
+        int rssi =
+                scanResult.level <= mThresholdSaturatedRssi24
+                        ? scanResult.level
+                        : mThresholdSaturatedRssi24;
+        score += (rssi + mRssiScoreOffset) * mRssiScoreSlope;
+
+        // 5GHz band bonus.
+        if (ScanResultUtil.is5GHz(scanResult)) {
+            score += mBand5GHzAward;
+        }
+
+        // Security award.
+        if (RoboCompatUtil.getInstance().isPasspoint(wifiConfiguration)) {
+            score += mPasspointSecurityAward;
+        } else if (!WifiConfigurationUtil.isConfigForOpenNetwork(wifiConfiguration)) {
+            score += mSecurityAward;
+        }
+
+        return score;
+    }
+}
diff --git a/tests/Android.mk b/tests/Android.mk
deleted file mode 100644
index b5759f3..0000000
--- a/tests/Android.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    android-support-test \
-    guava \
-    jsr305 \
-    mockito-target
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := NetworkRecommendationTests
-LOCAL_CERTIFICATE := platform
-
-LOCAL_INSTRUMENTATION_FOR := NetworkRecommendation
-
-include $(BUILD_PACKAGE)
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
deleted file mode 100644
index 3ebaaf3..0000000
--- a/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.networkrecommendation.tests">
-
-    <uses-permission android:name="android.permission.BIND_NETWORK_RECOMMENDATION_SERVICE"/>
-    <uses-permission android:name="android.permission.REQUEST_NETWORK_SCORES"/>
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-        android:targetPackage="com.android.networkrecommendation"
-        android:label="Tests for NetworkRecommendation">
-    </instrumentation>
-</manifest>
diff --git a/tests/src/com/android/networkrecommendation/DefaultNetworkRecommendationProviderTest.java b/tests/src/com/android/networkrecommendation/DefaultNetworkRecommendationProviderTest.java
deleted file mode 100644
index 5b78310..0000000
--- a/tests/src/com/android/networkrecommendation/DefaultNetworkRecommendationProviderTest.java
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Copyright (C) 2016 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.networkrecommendation;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.net.NetworkKey;
-import android.net.NetworkRecommendationProvider;
-import android.net.NetworkScoreManager;
-import android.net.RecommendationRequest;
-import android.net.RecommendationResult;
-import android.net.RssiCurve;
-import android.net.ScoredNetwork;
-import android.net.WifiKey;
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiSsid;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.SystemClock;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-/**
- * Tests the recommendation provider directly, to test internals of the provider rather than the
- * service's API.
- */
-@RunWith(AndroidJUnit4.class)
-public class DefaultNetworkRecommendationProviderTest {
-
-    private static final String GOOD_METERED_NETWORK_STRING_UNQUOTED = "Metered";
-    private static final String GOOD_METERED_NETWORK_STRING = "\"Metered\",aa:bb:cc:dd:ee:ff" +
-            "|10,-128,-128,-128,-128,-128,-128,-128,-128,20,20,20,20,-128|1|0|4K";
-    private static final RssiCurve GOOD_METERED_NETWORK_CURVE = new RssiCurve(
-            DefaultNetworkRecommendationProvider.CONSTANT_CURVE_START, 10 /* bucketWidth */,
-            new byte[]{-128, -128, -128, -128, -128, -128, -128, -128, 20, 20, 20, 20, -128},
-            0 /* defaultActiveNetworkBoost */);
-    private static final ScoredNetwork GOOD_METERED_NETWORK = new ScoredNetwork(
-            new NetworkKey(new WifiKey("\"Metered\"", "aa:bb:cc:dd:ee:ff")),
-            GOOD_METERED_NETWORK_CURVE, true /* meteredHint */, new Bundle());
-
-    private static final String GOOD_CAPTIVE_NETWORK_STRING_UNQUOTED = "Captive";
-    private static final String GOOD_CAPTIVE_NETWORK_STRING =
-            "\"Captive\",ff:ee:dd:cc:bb:aa"
-                    + "|18,-128,-128,-128,-128,-128,-128,21,21,21,-128|0|1|HD";
-    private static final RssiCurve GOOD_CAPTIVE_NETWORK_CURVE = new RssiCurve(
-            DefaultNetworkRecommendationProvider.CONSTANT_CURVE_START, 18 /* bucketWidth */,
-            new byte[]{-128, -128, -128, -128, -128, -128, 21, 21, 21, -128},
-            0 /* defaultActiveNetworkBoost */);
-    private static final ScoredNetwork GOOD_CAPTIVE_NETWORK;
-    static {
-        Bundle attributes = new Bundle();
-        attributes.putBoolean(ScoredNetwork.ATTRIBUTES_KEY_HAS_CAPTIVE_PORTAL, true);
-        GOOD_CAPTIVE_NETWORK = new ScoredNetwork(
-                new NetworkKey(new WifiKey("\"Captive\"", "ff:ee:dd:cc:bb:aa")),
-                GOOD_CAPTIVE_NETWORK_CURVE, false /* meteredHint */, attributes);
-    }
-
-    private static final String ANY_NETWORK_STRING_UNQUOTED = "AnySsid";
-    private static final String ANY_NETWORK_STRING =
-            "\"AnySsid\",00:00:00:00:00:00"
-                    + "|18,-128,-128,-128,-128,-128,-128,22,22,22,-128|0|0|NONE";
-    private static final RssiCurve ANY_NETWORK_CURVE = new RssiCurve(
-            DefaultNetworkRecommendationProvider.CONSTANT_CURVE_START, 18 /* bucketWidth */,
-            new byte[]{-128, -128, -128, -128, -128, -128, 22, 22, 22, -128},
-            0 /* defaultActiveNetworkBoost */);
-    private static final ScoredNetwork ANY_NETWORK = new ScoredNetwork(
-            new NetworkKey(new WifiKey("\"AnySsid\"", "ee:ee:ee:ee:ee:ee")),
-            ANY_NETWORK_CURVE, false /* meteredHint */, new Bundle());
-
-    private static final String ANY_NETWORK_SPECIFIC_STRING_UNQUOTED = "AnySsid";
-    private static final String ANY_NETWORK_SPECIFIC_STRING =
-            "\"AnySsid\",ee:ee:ee:ee:ee:ee"
-                    + "|18,-128,-128,-128,-128,-128,-128,23,23,23,-128|0|0|NONE";
-    private static final RssiCurve ANY_NETWORK_SPECIFIC_CURVE = new RssiCurve(
-            DefaultNetworkRecommendationProvider.CONSTANT_CURVE_START, 18 /* bucketWidth */,
-            new byte[]{-128, -128, -128, -128, -128, -128, 23, 23, 23, -128},
-            0 /* defaultActiveNetworkBoost */);
-    private static final ScoredNetwork ANY_NETWORK_SPECIFIC = new ScoredNetwork(
-            new NetworkKey(new WifiKey("\"AnySsid\"", "ee:ee:ee:ee:ee:ee")),
-            ANY_NETWORK_SPECIFIC_CURVE, false /* meteredHint */, new Bundle());
-
-    private static final String BAD_NETWORK_STRING_UNQUOTED = "Bad";
-    private static final String BAD_NETWORK_STRING =
-            "\"Bad\",aa:bb:cc:dd:ee:ff"
-                    + "|10,-128,-128,-128,-128,-128,-128,-128,-128,-128,-128,-128,-128,-128"
-                    + "|1|0|SD";
-    private static final RssiCurve BAD_NETWORK_CURVE =
-            new RssiCurve(
-                    DefaultNetworkRecommendationProvider.CONSTANT_CURVE_START,
-                    10 /* bucketWidth */,
-                    new byte[] {-128, -128, -128, -128, -128, -128,
-                            -128, -128, -128, -128, -128, -128, -128},
-                    0 /* defaultActiveNetworkBoost */);
-    private static final ScoredNetwork BAD_NETWORK =
-            new ScoredNetwork(
-                    new NetworkKey(new WifiKey("\"Bad\"", "aa:bb:cc:dd:ee:ff")),
-                    BAD_NETWORK_CURVE,
-                    true /* meteredHint */,
-                    new Bundle());
-
-    @Mock
-    private NetworkRecommendationProvider.ResultCallback mCallback;
-
-    @Mock
-    private NetworkScoreManager mNetworkScoreManager;
-
-    private DefaultNetworkRecommendationProvider.ScoreStorage mStorage;
-    private DefaultNetworkRecommendationProvider mProvider;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mStorage = new DefaultNetworkRecommendationProvider.ScoreStorage();
-        mProvider = new DefaultNetworkRecommendationProvider(
-                new Handler(Looper.getMainLooper()), mNetworkScoreManager, mStorage);
-    }
-
-    @Test
-    public void basicRecommendation() throws Exception {
-
-        ScanResult[] scanResults = new ScanResult[6];
-        for (int i = 0; i < 3; i++) {
-            scanResults[i] = TestUtil.createMockScanResult(i);
-        }
-
-        // For now we add directly to storage, but when we start calling
-        // networkScoreManager.updateScores, we'll have to adjust this test.
-        mProvider.addScoreForTest(GOOD_METERED_NETWORK);
-        {
-            ScanResult scanResult = new ScanResult();
-            scanResult.level = 115;
-            scanResult.SSID = GOOD_METERED_NETWORK_STRING_UNQUOTED;
-            scanResult.wifiSsid = WifiSsid.createFromAsciiEncoded(
-                    GOOD_METERED_NETWORK_STRING_UNQUOTED);
-            scanResult.BSSID = GOOD_METERED_NETWORK.networkKey.wifiKey.bssid;
-            scanResult.capabilities = "[ESS]";
-            scanResult.timestamp = SystemClock.elapsedRealtime() * 1000;
-            scanResults[3] = scanResult;
-        }
-
-        for (int i = 4; i < 6; i++) {
-            scanResults[i] = TestUtil.createMockScanResult(i);
-        }
-
-        RecommendationRequest request = new RecommendationRequest.Builder()
-                .setScanResults(scanResults)
-                .build();
-
-        RecommendationResult result = verifyAndCaptureResult(request);
-        assertEquals(GOOD_METERED_NETWORK.networkKey.wifiKey.ssid,
-                result.getWifiConfiguration().SSID);
-    }
-
-    @Test
-    public void recommendation_noScans_returnsCurrentConfig() throws Exception {
-        ScanResult[] scanResults = new ScanResult[0];
-
-        WifiConfiguration expectedConfig = new WifiConfiguration();
-        expectedConfig.SSID = "ssid";
-        expectedConfig.BSSID = "bssid";
-        RecommendationRequest request = new RecommendationRequest.Builder()
-                .setScanResults(scanResults)
-                .setDefaultWifiConfig(expectedConfig)
-                .build();
-
-        RecommendationResult result = verifyAndCaptureResult(request);
-        assertEquals(expectedConfig, result.getWifiConfiguration());
-    }
-
-    @Test
-    public void recommendation_noScans_noCurrentConfig_returnsEmpty() throws Exception {
-        ScanResult[] scanResults = new ScanResult[0];
-
-        RecommendationRequest request = new RecommendationRequest.Builder()
-                .setScanResults(scanResults)
-                .build();
-
-        RecommendationResult result = verifyAndCaptureResult(request);
-        assertNull(result.getWifiConfiguration());
-    }
-
-    @Test
-    public void scoreNetworks() throws Exception {
-        NetworkKey[] keys =
-                new NetworkKey[]{GOOD_METERED_NETWORK.networkKey, GOOD_CAPTIVE_NETWORK.networkKey};
-        mProvider.onRequestScores(keys);
-
-        verify(mNetworkScoreManager).updateScores(Mockito.any());
-    }
-
-    @Test
-    public void scoreNetworks_empty() throws Exception {
-        NetworkKey[] keys = new NetworkKey[]{};
-        mProvider.onRequestScores(keys);
-
-        verify(mNetworkScoreManager, times(0)).updateScores(Mockito.any());
-    }
-
-    @Test
-    public void dumpAddScores_goodMetered() {
-        String[] args = {"netrec", "addScore", GOOD_METERED_NETWORK_STRING};
-        mProvider.dump(null /* fd */, new PrintWriter(new StringWriter()), args);
-
-        ScoredNetwork[] scoredNetworks = verifyAndCaptureScoredNetworks();
-        assertEquals(1, scoredNetworks.length);
-        ScoredNetwork score = scoredNetworks[0];
-
-        assertEquals(GOOD_METERED_NETWORK.networkKey.wifiKey.ssid, score.networkKey.wifiKey.ssid);
-        assertEquals(GOOD_METERED_NETWORK.networkKey.wifiKey.bssid, score.networkKey.wifiKey.bssid);
-
-        assertEquals(GOOD_METERED_NETWORK.meteredHint, score.meteredHint);
-        assertEquals(
-                GOOD_METERED_NETWORK.attributes.getBoolean(
-                        ScoredNetwork.ATTRIBUTES_KEY_HAS_CAPTIVE_PORTAL),
-                score.attributes.getBoolean(ScoredNetwork.ATTRIBUTES_KEY_HAS_CAPTIVE_PORTAL));
-
-        assertEquals("Network curve does not match", GOOD_METERED_NETWORK_CURVE, score.rssiCurve);
-        assertEquals(
-                "Badge curve does not match",
-                DefaultNetworkRecommendationProvider.BADGE_CURVE_4K,
-                (RssiCurve) score.attributes.getParcelable(
-                        ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE));
-    }
-
-    @Test
-    public void dumpAddScores_bad() {
-        String[] args = {"netrec", "addScore", BAD_NETWORK_STRING};
-        mProvider.dump(null /* fd */, new PrintWriter(new StringWriter()), args);
-
-        ScoredNetwork[] scoredNetworks = verifyAndCaptureScoredNetworks();
-        assertEquals(1, scoredNetworks.length);
-        ScoredNetwork score = scoredNetworks[0];
-
-        assertEquals(BAD_NETWORK.networkKey.wifiKey.ssid, score.networkKey.wifiKey.ssid);
-        assertEquals(BAD_NETWORK.networkKey.wifiKey.bssid, score.networkKey.wifiKey.bssid);
-
-        assertEquals(BAD_NETWORK.meteredHint, score.meteredHint);
-        assertEquals(
-                BAD_NETWORK.attributes.getBoolean(ScoredNetwork.ATTRIBUTES_KEY_HAS_CAPTIVE_PORTAL),
-                score.attributes.getBoolean(ScoredNetwork.ATTRIBUTES_KEY_HAS_CAPTIVE_PORTAL));
-
-        assertEquals("Network curve does not match", BAD_NETWORK_CURVE, score.rssiCurve);
-        assertEquals(
-                "Badge curve does not match",
-                DefaultNetworkRecommendationProvider.BADGE_CURVE_SD,
-                (RssiCurve) score.attributes.getParcelable(
-                        ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE));
-    }
-
-    @Test
-    public void dumpAddScores_goodCaptivePortal() {
-        String[] args = {"addScore", GOOD_CAPTIVE_NETWORK_STRING};
-        mProvider.dump(null /* fd */, new PrintWriter(new StringWriter()), args);
-
-        ScoredNetwork[] scoredNetworks = verifyAndCaptureScoredNetworks();
-        assertEquals(1, scoredNetworks.length);
-        ScoredNetwork score = scoredNetworks[0];
-
-        assertEquals(GOOD_CAPTIVE_NETWORK.networkKey.wifiKey.ssid, score.networkKey.wifiKey.ssid);
-        assertEquals(GOOD_CAPTIVE_NETWORK.networkKey.wifiKey.bssid, score.networkKey.wifiKey.bssid);
-
-        assertEquals(GOOD_CAPTIVE_NETWORK.meteredHint, score.meteredHint);
-
-        assertEquals(
-                GOOD_CAPTIVE_NETWORK.attributes.getBoolean(
-                        ScoredNetwork.ATTRIBUTES_KEY_HAS_CAPTIVE_PORTAL),
-                score.attributes.getBoolean(ScoredNetwork.ATTRIBUTES_KEY_HAS_CAPTIVE_PORTAL));
-        assertEquals("Network curve does not match.", GOOD_CAPTIVE_NETWORK_CURVE, score.rssiCurve);
-        assertEquals(
-                "Badge curve does not match",
-                DefaultNetworkRecommendationProvider.BADGE_CURVE_HD,
-                (RssiCurve) score.attributes.getParcelable(
-                        ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE));
-    }
-
-    @Test
-    public void dumpAddScores_anySsid() {
-        String[] args = {"addScore", ANY_NETWORK_STRING};
-        mProvider.dump(null /* fd */, new PrintWriter(new StringWriter()), args);
-
-        // We don't update the platform with the any bssid score, but we do store it.
-        verify(mNetworkScoreManager, times(0)).updateScores(Mockito.any());
-
-        // We do store and serve the score, though:
-        ScoredNetwork score = mStorage.get(ANY_NETWORK.networkKey);
-        assertNotNull(score);
-
-        assertEquals(ANY_NETWORK.networkKey, score.networkKey);
-        assertEquals(ANY_NETWORK.meteredHint, score.meteredHint);
-        assertEquals(
-                ANY_NETWORK.attributes.getBoolean(
-                    ScoredNetwork.ATTRIBUTES_KEY_HAS_CAPTIVE_PORTAL),
-                score.attributes.getBoolean(ScoredNetwork.ATTRIBUTES_KEY_HAS_CAPTIVE_PORTAL));
-        assertEquals("Network curve does not match", ANY_NETWORK_CURVE, score.rssiCurve);
-        assertNull(
-                "Badge curve should not be set.",
-                (RssiCurve) score.attributes.getParcelable(
-                        ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE));
-    }
-
-    @Test
-    public void dumpAddScores_anySsid_useMoreSpecific() {
-        mProvider.dump(null /* fd */, new PrintWriter(new StringWriter()),
-                new String[] {"addScore", ANY_NETWORK_STRING});
-        verify(mNetworkScoreManager, times(0)).updateScores(Mockito.any());
-
-        mProvider.dump(null /* fd */, new PrintWriter(new StringWriter()),
-                new String[] {"addScore", ANY_NETWORK_SPECIFIC_STRING});
-        verify(mNetworkScoreManager).updateScores(Mockito.any());
-
-        // We don't update the platform with the any bssid score, but we do store it.
-        ScoredNetwork score = mStorage.get(ANY_NETWORK.networkKey);
-        assertNotNull(score);
-
-        assertEquals(ANY_NETWORK_SPECIFIC.networkKey, score.networkKey);
-        assertEquals(ANY_NETWORK_SPECIFIC.meteredHint, score.meteredHint);
-        assertEquals(
-                ANY_NETWORK_SPECIFIC.attributes.getBoolean(
-                    ScoredNetwork.ATTRIBUTES_KEY_HAS_CAPTIVE_PORTAL),
-                score.attributes.getBoolean(ScoredNetwork.ATTRIBUTES_KEY_HAS_CAPTIVE_PORTAL));
-        assertEquals("Network curve does not match", ANY_NETWORK_SPECIFIC_CURVE, score.rssiCurve);
-        assertNull(
-                "Badge curve should not be set.",
-                (RssiCurve) score.attributes.getParcelable(
-                        ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE));
-
-    }
-
-    private RecommendationResult verifyAndCaptureResult(
-            RecommendationRequest request) {
-        mProvider.onRequestRecommendation(request, mCallback);
-
-        ArgumentCaptor<RecommendationResult> resultCaptor =
-                ArgumentCaptor.forClass(RecommendationResult.class);
-        verify(mCallback).onResult(resultCaptor.capture());
-
-        return resultCaptor.getValue();
-    }
-
-    private ScoredNetwork[] verifyAndCaptureScoredNetworks() {
-        ArgumentCaptor<ScoredNetwork[]> resultCaptor = ArgumentCaptor.forClass(
-                ScoredNetwork[].class);
-        verify(mNetworkScoreManager).updateScores(resultCaptor.capture());
-        return resultCaptor.getValue();
-    }
-}
diff --git a/tests/src/com/android/networkrecommendation/DefaultNetworkRecommendationServiceTest.java b/tests/src/com/android/networkrecommendation/DefaultNetworkRecommendationServiceTest.java
deleted file mode 100644
index 75aff2b..0000000
--- a/tests/src/com/android/networkrecommendation/DefaultNetworkRecommendationServiceTest.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2016 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.networkrecommendation;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import android.content.Intent;
-import android.net.INetworkRecommendationProvider;
-import android.net.NetworkKey;
-import android.net.NetworkRecommendationProvider;
-import android.net.NetworkScoreManager;
-import android.net.RecommendationRequest;
-import android.net.RecommendationResult;
-import android.net.WifiKey;
-import android.net.wifi.ScanResult;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.IRemoteCallback;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.rule.ServiceTestRule;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-@RunWith(AndroidJUnit4.class)
-public class DefaultNetworkRecommendationServiceTest {
-
-    private static final int RESULT_LATCH_TIMEOUT_MILLIS = 2000;
-    private static final int WAIT_FOR_BIND_TIMEOUT_MILLIS = 2000;
-    private static final int SEQUENCE_ID = 11;
-
-    @Rule
-    public final ServiceTestRule mServiceRule = new ServiceTestRule();
-
-    private INetworkRecommendationProvider bind() throws TimeoutException {
-        Intent bindIntent = new Intent(InstrumentationRegistry.getTargetContext(),
-                DefaultNetworkRecommendationService.class);
-        bindIntent.setAction(NetworkScoreManager.ACTION_RECOMMEND_NETWORKS);
-
-        // https://code.google.com/p/android/issues/detail?id=200071
-        // bindService can occasionally returns null.
-        IBinder binder = null;
-        boolean interrupted = false;
-        try {
-            long startTime = SystemClock.elapsedRealtime();
-            long currentTime = startTime;
-            while (currentTime < startTime + WAIT_FOR_BIND_TIMEOUT_MILLIS) {
-                binder = mServiceRule.bindService(bindIntent);
-                if (binder != null) {
-                    return INetworkRecommendationProvider.Stub.asInterface(binder);
-                }
-                try {
-                    Thread.sleep(100);
-                } catch (InterruptedException e) {
-                    interrupted = true;
-                    currentTime = SystemClock.elapsedRealtime();
-                }
-            }
-            throw new TimeoutException("Unable to bind to service.");
-        } finally {
-            if (interrupted) {
-                Thread.currentThread().interrupt();
-            }
-        }
-    }
-
-    /**
-     * Assert that when we make a request we get a response with the proper sequence.
-     * <p />
-     * We do not assert the config given to us, because we're simply verifying the behavior of
-     * this service interacting with the provider. For recommendation tests, see
-     * {@link DefaultNetworkRecommendationProviderTest}.
-     */
-    @Test
-    public void requestRecommendation() throws Exception {
-        INetworkRecommendationProvider service = bind();
-
-        ScanResult[] scanResults = new ScanResult[5];
-        for (int i = 0; i < 5; i++) {
-            scanResults[i] = TestUtil.createMockScanResult(i);
-        }
-
-        RecommendationRequest request = new RecommendationRequest.Builder()
-                .setScanResults(scanResults)
-                .build();
-
-        Result result = requestRecommendation(service, request, SEQUENCE_ID);
-        synchronized (result) {
-            assertEquals(result.sequence, SEQUENCE_ID);
-        }
-    }
-
-    @Test
-    public void scoreNetworks() throws Exception {
-        INetworkRecommendationProvider service = bind();
-        service.requestScores(new NetworkKey[]{new NetworkKey(new WifiKey("\"ProperlyQuoted\"",
-                "aa:bb:cc:dd:ee:ff"))});
-    }
-
-    @Test
-    public void scoreNetworks_empty() throws Exception {
-        INetworkRecommendationProvider service = bind();
-        service.requestScores(new NetworkKey[]{});
-    }
-
-    @Test
-    public void scoreNetworks_invalid() throws Exception {
-        INetworkRecommendationProvider service = bind();
-        try {
-            service.requestScores(new NetworkKey[]{
-                    new NetworkKey(new WifiKey("ImproperlyQuoted", "aa:bb:cc:dd:ee:ff"))});
-            fail("An invalid SSID should throw an exception.");
-        } catch (IllegalArgumentException e) {
-            // Expected.
-        }
-    }
-
-    /**
-     * Make a network recommendation request. Be sure to synchronize on the result to access its
-     * values properly.
-     */
-    private Result requestRecommendation(INetworkRecommendationProvider service,
-            RecommendationRequest request, int seqId) throws RemoteException, InterruptedException {
-        final Result result = new Result();
-        final CountDownLatch latch = new CountDownLatch(1);
-        IRemoteCallback callback = new IRemoteCallback.Stub() {
-            @Override
-            public void sendResult(Bundle data) throws RemoteException {
-                synchronized (result) {
-                    result.sequence = data.getInt(NetworkRecommendationProvider.EXTRA_SEQUENCE);
-                    result.recommendation = data.getParcelable(
-                            NetworkRecommendationProvider.EXTRA_RECOMMENDATION_RESULT);
-                    latch.countDown();
-                }
-            }
-        };
-
-        service.requestRecommendation(request, callback, seqId);
-        latch.await(RESULT_LATCH_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
-        return result;
-    }
-
-    private static class Result {
-        int sequence;
-        RecommendationResult recommendation;
-    }
-}
diff --git a/tests/src/com/android/networkrecommendation/TestUtil.java b/tests/src/com/android/networkrecommendation/TestUtil.java
deleted file mode 100644
index 77d7aa7..0000000
--- a/tests/src/com/android/networkrecommendation/TestUtil.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2016 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.networkrecommendation;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.net.NetworkInfo;
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiManager;
-import android.net.wifi.WifiSsid;
-import android.os.SystemClock;
-
-/**
- * Utils for wifi tests.
- */
-public class TestUtil {
-
-    /** Create a scan result with some basic properties. */
-    public static ScanResult createMockScanResult(int i) {
-        ScanResult scanResult = new ScanResult();
-        scanResult.level = i;
-        scanResult.SSID = "ssid-" + i;
-        scanResult.wifiSsid = WifiSsid.createFromAsciiEncoded("ssid-" + i);
-        scanResult.BSSID = "aa:bb:cc:dd:ee:0" + i;
-        scanResult.capabilities = "[ESS]";
-        scanResult.timestamp = SystemClock.elapsedRealtime() * 1000;
-        return scanResult;
-    }
-
-    /** Send {@link WifiManager#NETWORK_STATE_CHANGED_ACTION} broadcast. */
-    public static void sendNetworkStateChanged(BroadcastReceiver broadcastReceiver,
-            Context context, NetworkInfo.DetailedState detailedState) {
-        Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
-        NetworkInfo networkInfo = new NetworkInfo(0, 0, "", "");
-        networkInfo.setDetailedState(detailedState, "", "");
-        intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
-        broadcastReceiver.onReceive(context, intent);
-    }
-
-    /** Send {@link WifiManager#WIFI_AP_STATE_CHANGED_ACTION} broadcast. */
-    public static void sendWifiApStateChanged(BroadcastReceiver broadcastReceiver,
-            Context context) {
-        Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
-        broadcastReceiver.onReceive(context, intent);
-    }
-
-    /** Send {@link WifiManager#SCAN_RESULTS_AVAILABLE_ACTION} broadcast. */
-    public static void sendScanResultsAvailable(BroadcastReceiver broadcastReceiver,
-            Context context) {
-        Intent intent = new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
-        broadcastReceiver.onReceive(context, intent);
-    }
-
-    /** Send {@link WifiManager#CONFIGURED_NETWORKS_CHANGED_ACTION} broadcast. */
-    public static void sendConfiguredNetworksChanged(BroadcastReceiver broadcastReceiver,
-            Context context) {
-        Intent intent = new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION);
-        broadcastReceiver.onReceive(context, intent);
-    }
-
-    /** Send {@link WifiManager#WIFI_STATE_CHANGED_ACTION} broadcast. */
-    public static void sendWifiStateChanged(BroadcastReceiver broadcastReceiver, Context context) {
-        Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
-        broadcastReceiver.onReceive(context, intent);
-    }
-}
diff --git a/tests/src/com/android/networkrecommendation/WifiNotificationControllerTest.java b/tests/src/com/android/networkrecommendation/WifiNotificationControllerTest.java
deleted file mode 100644
index d902e68..0000000
--- a/tests/src/com/android/networkrecommendation/WifiNotificationControllerTest.java
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright (C) 2017 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.networkrecommendation;
-
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.graphics.Bitmap;
-import android.net.NetworkInfo;
-import android.net.RecommendationRequest;
-import android.net.RecommendationResult;
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiManager;
-import android.net.wifi.WifiManager.ActionListener;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Unit tests for {@link com.android.networkrecommendation.WifiNotificationController}.
- */
-@RunWith(AndroidJUnit4.class)
-public class WifiNotificationControllerTest {
-    @Mock private Context mContext;
-    @Mock private WifiManager mWifiManager;
-    @Mock private NotificationManager mNotificationManager;
-    @Mock private WifiNotificationHelper mWifiNotificationHelper;
-    @Mock private SynchronousNetworkRecommendationProvider mNetworkRecommendationProvider;
-    private ContentResolver mContentResolver;
-    private Handler mHandler;
-    private WifiNotificationController mWifiNotificationController;
-    private int mNotificationsEnabledOriginalValue;
-
-    /**
-     * Internal BroadcastReceiver that WifiNotificationController uses to listen for broadcasts
-     * this is initialized by calling startServiceAndLoadDriver
-     */
-    private BroadcastReceiver mBroadcastReceiver;
-
-    /** Initialize objects before each test run. */
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        // Needed for the NotificationEnabledSettingObserver.
-        mContentResolver = InstrumentationRegistry.getTargetContext().getContentResolver();
-        mNotificationsEnabledOriginalValue =
-                Settings.Global.getInt(mContentResolver,
-                        Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 0);
-        Settings.Global.putInt(mContentResolver,
-                Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 1);
-        mHandler = new Handler(Looper.getMainLooper());
-
-        mWifiNotificationController = new WifiNotificationController(
-                mContext, mContentResolver, mHandler, mNetworkRecommendationProvider,
-                mWifiManager, mNotificationManager, mWifiNotificationHelper);
-        mWifiNotificationController.start();
-
-        ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
-                ArgumentCaptor.forClass(BroadcastReceiver.class);
-        verify(mContext)
-                .registerReceiver(broadcastReceiverCaptor.capture(), any(IntentFilter.class),
-                        anyString(), any(Handler.class));
-        mBroadcastReceiver = broadcastReceiverCaptor.getValue();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        Settings.Global.putInt(mContentResolver,
-                Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
-                mNotificationsEnabledOriginalValue);
-    }
-
-    private void setOpenAccessPoints(int numAccessPoints) {
-        List<ScanResult> scanResults = new ArrayList<>();
-        for (int i = 0; i < numAccessPoints; i++) {
-            ScanResult scanResult = createScanResult("testSSID" + i, "00:00:00:00:00:00");
-            scanResults.add(scanResult);
-        }
-        when(mWifiManager.getScanResults()).thenReturn(scanResults);
-    }
-
-    private ScanResult createScanResult(String ssid, String bssid) {
-        ScanResult scanResult = new ScanResult();
-        scanResult.capabilities = "[ESS]";
-        scanResult.SSID = ssid;
-        scanResult.BSSID = bssid;
-        return scanResult;
-    }
-
-    private WifiConfiguration createFakeConfig() {
-        WifiConfiguration config = new WifiConfiguration();
-        config.SSID = "\"TestSsid\"";
-        config.BSSID = "00:00:00:00:00:00";
-        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
-        return config;
-    }
-
-    private void createFakeBitmap() {
-        when(mWifiNotificationHelper.createNotificationBadgeBitmap(any(), any()))
-                .thenReturn(Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888));
-    }
-
-    /** Verifies that a notification is displayed (and retracted) given system events. */
-    @Test
-    public void verifyNotificationDisplayedWhenNetworkRecommended() throws Exception {
-        when(mWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_ENABLED);
-
-        TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendNetworkStateChanged(mBroadcastReceiver, mContext,
-                NetworkInfo.DetailedState.DISCONNECTED);
-        setOpenAccessPoints(3);
-        createFakeBitmap();
-
-        when(mNetworkRecommendationProvider.requestRecommendation(any(RecommendationRequest.class)))
-                .thenReturn(
-                        RecommendationResult.createConnectRecommendation(createFakeConfig()));
-
-        // The notification should not be displayed after only two scan results.
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-        verify(mNotificationManager, never())
-                .notify(any(String.class), anyInt(), any(Notification.class));
-
-        // Changing to and from "SCANNING" state should not affect the counter.
-        TestUtil.sendNetworkStateChanged(mBroadcastReceiver, mContext,
-                NetworkInfo.DetailedState.SCANNING);
-        TestUtil.sendNetworkStateChanged(mBroadcastReceiver, mContext,
-                NetworkInfo.DetailedState.DISCONNECTED);
-        verify(mNotificationManager, never())
-                .notify(any(String.class), anyInt(), any(Notification.class));
-        // The third scan result notification will trigger the notification.
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-        verify(mWifiNotificationHelper).createMainNotification(any(WifiConfiguration.class),
-                any(Bitmap.class));
-        verify(mNotificationManager)
-                .notify(any(String.class), anyInt(), any(Notification.class));
-        verify(mNotificationManager, never())
-                .cancelAsUser(any(String.class), anyInt(), any(UserHandle.class));
-    }
-
-    /** Verifies that a notification is not displayed for bad networks. */
-    @Test
-    public void verifyNotificationNotDisplayedWhenNoNetworkRecommended() throws Exception {
-        when(mWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_ENABLED);
-
-        TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendNetworkStateChanged(mBroadcastReceiver, mContext,
-                NetworkInfo.DetailedState.DISCONNECTED);
-        setOpenAccessPoints(3);
-        createFakeBitmap();
-
-        // Recommendation result with no WifiConfiguration returned.
-        when(mNetworkRecommendationProvider.requestRecommendation(any(RecommendationRequest.class)))
-                .thenReturn(RecommendationResult.createDoNotConnectRecommendation());
-
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-        verify(mNotificationManager, never())
-                .notify(any(String.class), anyInt(), any(Notification.class));
-
-        // DoNotConnect Recommendation result.
-        when(mNetworkRecommendationProvider.requestRecommendation(any(RecommendationRequest.class)))
-                .thenReturn(RecommendationResult.createDoNotConnectRecommendation());
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-        verify(mNotificationManager, never())
-                .notify(any(String.class), anyInt(), any(Notification.class));
-    }
-
-    /**
-     * Verifies the notifications flow (Connect -> connecting -> connected) when user clicks
-     * on Connect button.
-     */
-    @Test
-    public void verifyNotificationsFlowOnConnectToNetwork() {
-        when(mWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_ENABLED);
-
-        TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendNetworkStateChanged(mBroadcastReceiver, mContext,
-                NetworkInfo.DetailedState.DISCONNECTED);
-        setOpenAccessPoints(3);
-        createFakeBitmap();
-        when(mNetworkRecommendationProvider.requestRecommendation(any(RecommendationRequest.class)))
-                .thenReturn(
-                        RecommendationResult.createConnectRecommendation(createFakeConfig()));
-
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-        verify(mWifiNotificationHelper).createMainNotification(any(WifiConfiguration.class),
-                any(Bitmap.class));
-        verify(mNotificationManager)
-                .notify(any(String.class), anyInt(), any(Notification.class));
-
-        // Send connect intent, should attempt to connect to Wi-Fi
-        Intent intent = new Intent(
-                WifiNotificationController.ACTION_CONNECT_TO_RECOMMENDED_NETWORK);
-        mBroadcastReceiver.onReceive(mContext, intent);
-        verify(mWifiManager).connect(any(WifiConfiguration.class), any(ActionListener.class));
-        verify(mWifiNotificationHelper).createConnectingNotification(any(WifiConfiguration.class),
-                any(Bitmap.class));
-
-        // Show connecting notification.
-        verify(mNotificationManager, times(2))
-                .notify(any(String.class), anyInt(), any(Notification.class));
-        // Verify callback to dismiss connecting notification exists.
-        assertTrue(mHandler.hasCallbacks(
-                mWifiNotificationController.mShowFailedToConnectNotificationRunnable));
-
-        // Verify show connected notification.
-        TestUtil.sendNetworkStateChanged(mBroadcastReceiver, mContext,
-                NetworkInfo.DetailedState.CONNECTED);
-        verify(mWifiNotificationHelper).createConnectedNotification(any(WifiConfiguration.class),
-                any(Bitmap.class));
-        verify(mNotificationManager, times(3))
-                .notify(any(String.class), anyInt(), any(Notification.class));
-
-        // Verify callback to dismiss connected notification exists.
-        assertTrue(mHandler.hasCallbacks(
-                mWifiNotificationController.mDismissNotificationRunnable));
-    }
-}
diff --git a/tests/src/com/android/networkrecommendation/WifiWakeupControllerTest.java b/tests/src/com/android/networkrecommendation/WifiWakeupControllerTest.java
deleted file mode 100644
index 3869a71..0000000
--- a/tests/src/com/android/networkrecommendation/WifiWakeupControllerTest.java
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * Copyright (C) 2017 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.networkrecommendation;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyList;
-import static org.mockito.Matchers.anyMap;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-import android.app.NotificationManager;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.IntentFilter;
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiManager;
-import android.net.wifi.WifiSsid;
-import android.os.Handler;
-import android.os.Looper;
-import android.provider.Settings;
-import android.support.test.runner.AndroidJUnit4;
-
-import com.google.android.collect.Lists;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-/**
- * Unit tests for {@link WifiWakeupController}.
- */
-@RunWith(AndroidJUnit4.class)
-public class WifiWakeupControllerTest {
-    private static final ScanResult OPEN_SCAN_RESULT = buildScanResult("ssid");
-    private static final ScanResult SAVED_SCAN_RESULT = buildScanResult("ssid1");
-    private static final ScanResult SAVED_SCAN_RESULT2 = buildScanResult("ssid2");
-    private static final ScanResult SAVED_SCAN_RESULT_EXTERNAL = buildScanResult("ssid3");
-
-    private static final WifiConfiguration SAVED_WIFI_CONFIGURATION = new WifiConfiguration();
-    private static final WifiConfiguration SAVED_WIFI_CONFIGURATION2 = new WifiConfiguration();
-    private static final WifiConfiguration SAVED_WIFI_CONFIGURATION_EXTERNAL =
-            new WifiConfiguration();
-
-    static {
-        SAVED_WIFI_CONFIGURATION.SSID = "\"" + SAVED_SCAN_RESULT.SSID + "\"";
-        SAVED_WIFI_CONFIGURATION.status = WifiConfiguration.Status.CURRENT;
-        SAVED_WIFI_CONFIGURATION.validatedInternetAccess = true;
-        SAVED_WIFI_CONFIGURATION2.SSID = "\"" + SAVED_SCAN_RESULT.SSID + "\"";
-        SAVED_WIFI_CONFIGURATION2.status = WifiConfiguration.Status.ENABLED;
-        SAVED_WIFI_CONFIGURATION2.validatedInternetAccess = true;
-        SAVED_WIFI_CONFIGURATION_EXTERNAL.SSID = "\"" + SAVED_SCAN_RESULT_EXTERNAL.SSID + "\"";
-        SAVED_WIFI_CONFIGURATION_EXTERNAL.useExternalScores = true;
-        SAVED_WIFI_CONFIGURATION_EXTERNAL.status = WifiConfiguration.Status.ENABLED;
-        SAVED_WIFI_CONFIGURATION_EXTERNAL.validatedInternetAccess = true;
-    }
-
-    private static ScanResult buildScanResult(String ssid) {
-        ScanResult scanResult = new ScanResult(WifiSsid.createFromAsciiEncoded(ssid),
-                "00:00:00:00:00:00", 0L, -1, null, "", 0, 0, 0);
-        scanResult.informationElements = new ScanResult.InformationElement[0];
-        return scanResult;
-    }
-
-    @Mock private Context mContext;
-    @Mock private NotificationManager mNotificationManager;
-    @Mock private ContentResolver mContentResolver;
-    @Mock private WifiWakeupNetworkSelector mWifiWakeupNetworkSelector;
-    @Mock private WifiWakeupNotificationHelper mWifiWakeupNotificationHelper;
-    @Mock private WifiManager mWifiManager;
-    @Captor private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor;
-
-    private WifiWakeupController mWifiWakeupController;
-    private BroadcastReceiver mBroadcastReceiver;
-
-    private int mWifiWakeupEnabledOriginalValue;
-    private int mAirplaneModeOriginalValue;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        mWifiWakeupEnabledOriginalValue =
-                Settings.Global.getInt(mContentResolver, Settings.Global.WIFI_WAKEUP_ENABLED, 0);
-        mAirplaneModeOriginalValue =
-                Settings.Global.getInt(mContentResolver, Settings.Global.AIRPLANE_MODE_ON, 0);
-        Settings.Global.putInt(mContentResolver, Settings.Global.WIFI_WAKEUP_ENABLED, 1);
-        Settings.Global.putInt(mContentResolver, Settings.Global.AIRPLANE_MODE_ON, 0);
-        when(mWifiManager.getWifiApState()).thenReturn(WifiManager.WIFI_AP_STATE_DISABLED);
-
-        mWifiWakeupController = new WifiWakeupController(mContext, mContentResolver,
-                Looper.getMainLooper(), mWifiManager, mWifiWakeupNetworkSelector,
-                mWifiWakeupNotificationHelper);
-        mWifiWakeupController.start();
-
-        verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
-                any(IntentFilter.class), anyString(), any(Handler.class));
-        mBroadcastReceiver = mBroadcastReceiverCaptor.getValue();
-    }
-
-    @After
-    public void tearDown() {
-        Settings.Global.putInt(mContentResolver, Settings.Global.WIFI_WAKEUP_ENABLED,
-                mWifiWakeupEnabledOriginalValue);
-        Settings.Global.putInt(mContentResolver, Settings.Global.AIRPLANE_MODE_ON,
-                mAirplaneModeOriginalValue);
-    }
-
-    /**
-     * When the NetworkRecommendationService associated with this WifiWakeupController is unbound,
-     * this WifiWakeupController should no longer function.
-     */
-    @Test
-    public void wifiWakeupControllerStopped() {
-        mWifiWakeupController.stop();
-
-        verify(mContext).unregisterReceiver(mBroadcastReceiver);
-    }
-
-    /**
-     * When Wi-Fi is disabled and a saved network is in the scan list, and then this network is not
-     * in the scan list 3x, and then it is, Wi-Fi should be enabled.
-     */
-    @Test
-    public void wifiEnabled_userDisabledWifiNearSavedNetwork_thenLeaves_thenMovesBack() {
-        when(mWifiManager.getConfiguredNetworks()).thenReturn(
-                Lists.newArrayList(SAVED_WIFI_CONFIGURATION));
-        when(mWifiManager.getScanResults()).thenReturn(
-                Lists.newArrayList(SAVED_SCAN_RESULT),
-                Lists.newArrayList(OPEN_SCAN_RESULT),
-                Lists.newArrayList(OPEN_SCAN_RESULT),
-                Lists.newArrayList(OPEN_SCAN_RESULT),
-                Lists.newArrayList(SAVED_SCAN_RESULT));
-        when(mWifiWakeupNetworkSelector.selectNetwork(anyMap(), anyList()))
-                .thenReturn(null, SAVED_WIFI_CONFIGURATION);
-        when(mWifiManager.getWifiState())
-                .thenReturn(WifiManager.WIFI_STATE_ENABLED, WifiManager.WIFI_STATE_DISABLED);
-
-        TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendConfiguredNetworksChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-        TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-
-        verify(mWifiManager, never()).setWifiEnabled(true);
-
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-
-        verify(mWifiManager).setWifiEnabled(true);
-        verify(mWifiWakeupNotificationHelper)
-                .maybeShowWifiEnabledNotification(SAVED_WIFI_CONFIGURATION);
-    }
-
-    /**
-     * When Wi-Fi is disabled and a saved network is in the scan list, and then another scan result
-     * comes in 3x with only a different saved network, Wi-Fi should be enabled.
-     */
-    @Test
-    public void wifiEnabled_userDisabledWifiNearSavedNetwork_thenMovesToAnotherSavedNetwork() {
-        when(mWifiManager.getConfiguredNetworks()).thenReturn(
-                Lists.newArrayList(SAVED_WIFI_CONFIGURATION, SAVED_WIFI_CONFIGURATION2));
-        when(mWifiManager.getScanResults()).thenReturn(
-                Lists.newArrayList(SAVED_SCAN_RESULT),
-                Lists.newArrayList(SAVED_SCAN_RESULT2));
-        when(mWifiWakeupNetworkSelector.selectNetwork(anyMap(), anyList()))
-                .thenReturn(SAVED_WIFI_CONFIGURATION2);
-        when(mWifiManager.getWifiState())
-                .thenReturn(WifiManager.WIFI_STATE_ENABLED, WifiManager.WIFI_STATE_DISABLED);
-
-        TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendConfiguredNetworksChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-        TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext);
-
-        verify(mWifiManager, never()).setWifiEnabled(true);
-
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-
-        verify(mWifiManager).setWifiEnabled(true);
-        verify(mWifiWakeupNotificationHelper)
-                .maybeShowWifiEnabledNotification(SAVED_WIFI_CONFIGURATION2);
-    }
-
-    /**
-     * When a user disables Wi-Fi when there is a saved network marked with
-     * {@link WifiConfiguration#useExternalScores} in the scan list, Wi-Fi should not be enabled if
-     * the {@link WifiWakeupNetworkSelector} does not return an ssid.
-     *
-     * When {@link WifiWakeupNetworkSelector} does return an ssid, Wi-Fi should
-     * be enabled (in absence of a scan list without the saved network) because networks marked
-     * with external scores are not tracked by {@link WifiWakeupController}.
-     */
-    @Test
-    public void wifiEnabled_userDisablesWifiNearExternallyScoredNetwork_thenNetworkIsSelected() {
-        when(mWifiManager.getConfiguredNetworks()).thenReturn(
-                Lists.newArrayList(SAVED_WIFI_CONFIGURATION, SAVED_WIFI_CONFIGURATION_EXTERNAL));
-        when(mWifiManager.getScanResults())
-                .thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT_EXTERNAL));
-        when(mWifiWakeupNetworkSelector.selectNetwork(anyMap(), anyList()))
-                .thenReturn(null, SAVED_WIFI_CONFIGURATION_EXTERNAL);
-        when(mWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_DISABLED);
-
-        TestUtil.sendConfiguredNetworksChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-
-        verify(mWifiManager, never()).setWifiEnabled(true);
-
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-
-        verify(mWifiManager).setWifiEnabled(true);
-        verify(mWifiWakeupNotificationHelper)
-                .maybeShowWifiEnabledNotification(SAVED_WIFI_CONFIGURATION_EXTERNAL);
-    }
-
-    /**
-     * When Wi-Fi is enabled and a saved network is in the scan list, Wi-Fi should not be enabled.
-     */
-    @Test
-    public void wifiNotEnabled_wifiAlreadyEnabled() {
-        when(mWifiManager.getConfiguredNetworks()).thenReturn(
-                Lists.newArrayList(SAVED_WIFI_CONFIGURATION, SAVED_WIFI_CONFIGURATION_EXTERNAL));
-        when(mWifiManager.getScanResults())
-                .thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT));
-        when(mWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_ENABLED);
-
-        TestUtil.sendConfiguredNetworksChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-
-        verifyZeroInteractions(mWifiWakeupNetworkSelector);
-        verify(mWifiManager, never()).setWifiEnabled(true);
-    }
-
-    /**
-     * When Wi-Fi is disabled and a saved network is in the scan list, but
-     * {@link WifiWakeupNetworkSelector}, does not choose this network, Wi-Fi should not be enabled.
-     */
-    @Test
-    public void wifiNotEnabled_userNearSavedNetworkButNotSelected() {
-        when(mWifiManager.getConfiguredNetworks()).thenReturn(
-                Lists.newArrayList(SAVED_WIFI_CONFIGURATION, SAVED_WIFI_CONFIGURATION_EXTERNAL));
-        when(mWifiManager.getScanResults())
-                .thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT));
-        when(mWifiWakeupNetworkSelector.selectNetwork(anyMap(), anyList())).thenReturn(null);
-        when(mWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_DISABLED);
-
-        TestUtil.sendConfiguredNetworksChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-
-        verify(mWifiManager, never()).setWifiEnabled(true);
-    }
-
-    /**
-     * If Wi-Fi is disabled and a saved network is in the scan list, Wi-Fi should not be enabled
-     * if the user has not enabled the wifi wakeup feature.
-     */
-    @Test
-    public void wifiNotEnabled_userDisablesWifiWakeupFeature() {
-        Settings.Global.putInt(mContentResolver, Settings.Global.WIFI_WAKEUP_ENABLED, 0);
-        when(mWifiManager.getConfiguredNetworks()).thenReturn(
-                Lists.newArrayList(SAVED_WIFI_CONFIGURATION, SAVED_WIFI_CONFIGURATION_EXTERNAL));
-        when(mWifiManager.getScanResults())
-                .thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT));
-        when(mWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_DISABLED);
-
-        mWifiWakeupController.mContentObserver.onChange(true);
-        TestUtil.sendConfiguredNetworksChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-
-        verifyZeroInteractions(mWifiWakeupNetworkSelector);
-        verify(mWifiManager, never()).setWifiEnabled(true);
-    }
-
-    /**
-     * If Wi-Fi is disabled and a saved network is in the scan list, Wi-Fi should not be enabled if
-     * the user is in airplane mode.
-     */
-    @Test
-    public void wifiNotEnabled_userIsInAirplaneMode() {
-        Settings.Global.putInt(mContentResolver, Settings.Global.AIRPLANE_MODE_ON, 1);
-        when(mWifiManager.getConfiguredNetworks()).thenReturn(
-                Lists.newArrayList(SAVED_WIFI_CONFIGURATION, SAVED_WIFI_CONFIGURATION_EXTERNAL));
-        when(mWifiManager.getScanResults())
-                .thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT));
-        when(mWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_DISABLED);
-
-        mWifiWakeupController.mContentObserver.onChange(true);
-        TestUtil.sendConfiguredNetworksChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-
-        verifyZeroInteractions(mWifiWakeupNetworkSelector);
-        verify(mWifiManager, never()).setWifiEnabled(true);
-    }
-
-    /**
-     * If Wi-Fi is disabled and a saved network is in the scan list, Wi-Fi should not be enabled if
-     * the wifi AP state is not disabled.
-     */
-    @Test
-    public void wifiNotEnabled_wifiApStateIsNotDisabled() {
-        when(mWifiManager.getConfiguredNetworks()).thenReturn(
-                Lists.newArrayList(SAVED_WIFI_CONFIGURATION, SAVED_WIFI_CONFIGURATION_EXTERNAL));
-        when(mWifiManager.getScanResults())
-                .thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT));
-        when(mWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_DISABLED);
-        when(mWifiManager.getWifiApState()).thenReturn(WifiManager.WIFI_AP_STATE_ENABLED);
-
-        mWifiWakeupController.mContentObserver.onChange(true);
-        TestUtil.sendConfiguredNetworksChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendWifiApStateChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-
-        verifyZeroInteractions(mWifiWakeupNetworkSelector);
-        verify(mWifiManager, never()).setWifiEnabled(true);
-    }
-
-    /**
-     * If Wi-Fi is disabled when a saved network is the scan list, Wi-Fi should not be enabled no
-     * matter how many scans are performed that include the saved network.
-     */
-    @Test
-    public void wifiNotEnabled_userDisablesWifiNearSavedNetwork_thenDoesNotLeave() {
-        when(mWifiManager.getConfiguredNetworks()).thenReturn(
-                Lists.newArrayList(SAVED_WIFI_CONFIGURATION, SAVED_WIFI_CONFIGURATION_EXTERNAL));
-        when(mWifiManager.getScanResults())
-                .thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT));
-
-        TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendConfiguredNetworksChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-        TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-
-        verifyZeroInteractions(mWifiWakeupNetworkSelector);
-        verify(mWifiManager, never()).setWifiEnabled(true);
-    }
-
-    /**
-     * If Wi-Fi is disabled when a saved network is in the scan list, and then that saved network
-     * is removed, Wi-Fi is not enabled even if the user leaves range of that network and returns.
-     */
-    @Test
-    public void wifiNotEnabled_userDisablesWifiNearSavedNetwork_thenRemovesNetwork_thenStays() {
-        when(mWifiManager.getConfiguredNetworks()).thenReturn(
-                Lists.newArrayList(SAVED_WIFI_CONFIGURATION),
-                Lists.<WifiConfiguration>newArrayList());
-        when(mWifiManager.getScanResults())
-                .thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT))
-                .thenReturn(Lists.<ScanResult>newArrayList())
-                .thenReturn(Lists.newArrayList(SAVED_SCAN_RESULT));
-        when(mWifiWakeupNetworkSelector.selectNetwork(anyMap(), anyList())).thenReturn(null);
-        when(mWifiManager.getWifiState())
-                .thenReturn(WifiManager.WIFI_STATE_ENABLED, WifiManager.WIFI_STATE_DISABLED);
-
-        TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendConfiguredNetworksChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-        TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendConfiguredNetworksChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-
-        verify(mWifiManager, never()).setWifiEnabled(true);
-    }
-
-    /**
-     * If Wi-Fi is disabled when 2 saved networks are in the scan list, and then a scan result
-     * comes in with only 1 saved network 3x, Wi-Fi should not be enabled.
-     */
-    @Test
-    public void wifiNotEnabled_userDisablesWifiNear2SavedNetworks_thenLeavesRangeOfOneOfThem() {
-        when(mWifiManager.getConfiguredNetworks()).thenReturn(
-                Lists.newArrayList(SAVED_WIFI_CONFIGURATION, SAVED_WIFI_CONFIGURATION2));
-        when(mWifiManager.getScanResults()).thenReturn(
-                Lists.newArrayList(SAVED_SCAN_RESULT,
-                        SAVED_SCAN_RESULT2),
-                Lists.newArrayList(SAVED_SCAN_RESULT));
-        when(mWifiManager.getWifiState())
-                .thenReturn(WifiManager.WIFI_STATE_ENABLED, WifiManager.WIFI_STATE_DISABLED);
-
-        TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendConfiguredNetworksChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-        TestUtil.sendWifiStateChanged(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-        TestUtil.sendScanResultsAvailable(mBroadcastReceiver, mContext);
-
-        verifyZeroInteractions(mWifiWakeupNetworkSelector);
-        verify(mWifiManager, never()).setWifiEnabled(true);
-    }
-
-    /** Test dump() does not crash. */
-    @Test
-    public void testDump() {
-        StringWriter stringWriter = new StringWriter();
-        mWifiWakeupController.dump(
-                new FileDescriptor(), new PrintWriter(stringWriter), new String[0]);
-    }
-}
diff --git a/tests/src/com/android/networkrecommendation/WifiWakeupNetworkSelectorTest.java b/tests/src/com/android/networkrecommendation/WifiWakeupNetworkSelectorTest.java
deleted file mode 100644
index c54803c..0000000
--- a/tests/src/com/android/networkrecommendation/WifiWakeupNetworkSelectorTest.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2017 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.networkrecommendation;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.when;
-
-import android.content.res.Resources;
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiSsid;
-import android.support.test.runner.AndroidJUnit4;
-import android.util.ArrayMap;
-
-import com.google.android.collect.Lists;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.List;
-
-/**
- * Unit tests for {@link WifiWakeupNetworkSelector}
- */
-@RunWith(AndroidJUnit4.class)
-public class WifiWakeupNetworkSelectorTest {
-    private static final String SSID = "ssid";
-    private static final String SSID2 = "ssid2";
-
-    private static final WifiConfiguration WIFI_CONFIGURATION_PSK = new WifiConfiguration();
-    private static final WifiConfiguration WIFI_CONFIGURATION_NONE = new WifiConfiguration();
-    private static final ArrayMap<String, WifiConfiguration> SAVED_WIFI_CONFIGURATION_MAP =
-            new ArrayMap<>();
-
-    static {
-        WIFI_CONFIGURATION_PSK.SSID = "\"" + SSID + "\"";
-        WIFI_CONFIGURATION_PSK.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        SAVED_WIFI_CONFIGURATION_MAP.put(SSID, WIFI_CONFIGURATION_PSK);
-
-        WIFI_CONFIGURATION_NONE.SSID = "\"" + SSID2 + "\"";
-        WIFI_CONFIGURATION_NONE.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
-        SAVED_WIFI_CONFIGURATION_MAP.put(SSID2, WIFI_CONFIGURATION_NONE);
-    }
-
-    private static ScanResult buildScanResult(String ssid, int level, int frequency, String caps) {
-        return new ScanResult(WifiSsid.createFromAsciiEncoded(ssid),
-                "00:00:00:00:00:00", 0L, -1, null, caps, level, frequency, 0);
-    }
-
-    private static final int MIN_QUALIFIED_24 = -73;
-    private static final int MIN_QUALIFIED_5 = -70;
-    private static final int FREQUENCY_24 = 2450;
-    private static final int FREQUENCY_5 = 5000;
-    private static final String CAPABILITIES_NONE = "";
-    private static final String CAPABILITIES_PSK = "PSK";
-
-    @Mock private Resources mResources;
-
-    private WifiWakeupNetworkSelector mWifiWakeupNetworkSelector;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        when(mResources.getInteger(
-                R.integer.config_netrec_wifi_score_low_rssi_threshold_24GHz))
-                .thenReturn(MIN_QUALIFIED_24);
-        when(mResources.getInteger(
-                R.integer.config_netrec_wifi_score_low_rssi_threshold_5GHz))
-                .thenReturn(MIN_QUALIFIED_5);
-        when(mResources.getInteger(
-                R.integer.config_netrec_5GHz_preference_boost_factor))
-                .thenReturn(100);
-
-        mWifiWakeupNetworkSelector = new WifiWakeupNetworkSelector(mResources);
-    }
-
-    @Test
-    public void testSelectNetwork_noSavedNetworksInScanResults() {
-        List<ScanResult> scanResults = Lists.newArrayList(
-                buildScanResult("blah", MIN_QUALIFIED_5 + 1, FREQUENCY_5, CAPABILITIES_NONE),
-                buildScanResult("blahtoo", MIN_QUALIFIED_24 + 1, FREQUENCY_24, CAPABILITIES_NONE));
-
-        WifiConfiguration selectedNetwork = mWifiWakeupNetworkSelector
-                .selectNetwork(SAVED_WIFI_CONFIGURATION_MAP, scanResults);
-
-        assertNull(selectedNetwork);
-    }
-
-    @Test
-    public void testSelectNetwork_noQualifiedSavedNetworks() {
-        List<ScanResult> scanResults = Lists.newArrayList(
-                buildScanResult(SSID2, MIN_QUALIFIED_5 - 1, FREQUENCY_5, CAPABILITIES_NONE),
-                buildScanResult(SSID2, MIN_QUALIFIED_24 - 1, FREQUENCY_24, CAPABILITIES_NONE));
-
-        WifiConfiguration selectedNetwork = mWifiWakeupNetworkSelector
-                .selectNetwork(SAVED_WIFI_CONFIGURATION_MAP, scanResults);
-
-        assertNull(selectedNetwork);
-    }
-
-    @Test
-    public void testSelectNetwork_noMatchingScanResults() {
-        List<ScanResult> scanResults = Lists.newArrayList(
-                buildScanResult(SSID, MIN_QUALIFIED_5 + 1, FREQUENCY_5, CAPABILITIES_NONE),
-                buildScanResult(SSID, MIN_QUALIFIED_24 + 1, FREQUENCY_24, CAPABILITIES_NONE));
-
-        WifiConfiguration selectedNetwork = mWifiWakeupNetworkSelector
-                .selectNetwork(SAVED_WIFI_CONFIGURATION_MAP, scanResults);
-
-        assertNull(selectedNetwork);
-    }
-
-    @Test
-    public void testSelectNetwork_secureNetworkOverUnsecure() {
-        List<ScanResult> scanResults = Lists.newArrayList(
-                buildScanResult(SSID, MIN_QUALIFIED_5 + 1, FREQUENCY_5, CAPABILITIES_PSK),
-                buildScanResult(SSID2, MIN_QUALIFIED_5 + 1, FREQUENCY_5, CAPABILITIES_NONE));
-
-        WifiConfiguration selectedNetwork = mWifiWakeupNetworkSelector
-                .selectNetwork(SAVED_WIFI_CONFIGURATION_MAP, scanResults);
-
-        assertEquals(WIFI_CONFIGURATION_PSK, selectedNetwork);
-    }
-}
diff --git a/tests/src/com/android/networkrecommendation/WifiWakeupNotificationHelperTest.java b/tests/src/com/android/networkrecommendation/WifiWakeupNotificationHelperTest.java
deleted file mode 100644
index 2091335..0000000
--- a/tests/src/com/android/networkrecommendation/WifiWakeupNotificationHelperTest.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2016 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.networkrecommendation;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.net.wifi.WifiSsid;
-import android.os.Handler;
-import android.os.Looper;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.Set;
-
-/**
- * Unit tests for {@link WifiWakeupNetworkSelector}
- */
-@RunWith(AndroidJUnit4.class)
-public class WifiWakeupNotificationHelperTest {
-    private static final String SSID = "ssid";
-    private static final WifiConfiguration WIFI_CONFIGURATION = new WifiConfiguration();
-
-    static {
-        WIFI_CONFIGURATION.SSID = "\"" + SSID + "\"";
-    }
-
-    private Context mContext;
-    @Mock private NotificationManager mNotificationManager;
-    @Mock private WifiManager mWifiManager;
-    private SharedPreferences mSharedPreferences;
-    private String mSharedPreferenceName;
-
-    private WifiWakeupNotificationHelper mWifiWakeupNotificationHelper;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        mContext = InstrumentationRegistry.getTargetContext();
-        mSharedPreferenceName = "WifiWakeupNotificationHelperTest";
-        mSharedPreferences = mContext.getSharedPreferences(mSharedPreferenceName,
-                Context.MODE_PRIVATE);
-
-        mWifiWakeupNotificationHelper = new WifiWakeupNotificationHelper(mContext,
-                mContext.getResources(), new Handler(Looper.getMainLooper()), mNotificationManager,
-                mWifiManager, mSharedPreferences);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mContext.deleteSharedPreferences(mSharedPreferenceName);
-    }
-
-    @Test
-    public void notificationShowsOncePerSsid() {
-        mWifiWakeupNotificationHelper.maybeShowWifiEnabledNotification(WIFI_CONFIGURATION);
-        mWifiWakeupNotificationHelper.maybeShowWifiEnabledNotification(WIFI_CONFIGURATION);
-
-        verify(mNotificationManager, times(1))
-                .notify(anyString(), anyInt(), any(Notification.class));
-        Set<String> ssidSet = mSharedPreferences.getStringSet(
-                WifiWakeupNotificationHelper.KEY_SHOWN_SSIDS, null);
-        assertEquals(1, ssidSet.size());
-        assertTrue(ssidSet.contains(WIFI_CONFIGURATION.SSID));
-    }
-
-    @Test
-    public void notificationCanceledWhenNeverConnected() {
-        mWifiWakeupNotificationHelper.maybeShowWifiEnabledNotification(WIFI_CONFIGURATION);
-
-        mWifiWakeupNotificationHelper.mCancelNotification.run();
-
-        verify(mNotificationManager).cancel(anyString(), anyInt());
-    }
-
-    @Test
-    public void notificationCanceledWhenWifiDisabled() {
-        mWifiWakeupNotificationHelper.maybeShowWifiEnabledNotification(WIFI_CONFIGURATION);
-
-        when(mWifiManager.isWifiEnabled()).thenReturn(false);
-
-        mWifiWakeupNotificationHelper.mBroadcastReceiver.onReceive(mContext,
-                new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
-
-        verify(mNotificationManager).cancel(anyString(), anyInt());
-    }
-
-    @Test
-    public void notificationCanceledWhenSsidChanged() {
-        WifiInfo firstWifiInfo = new WifiInfo();
-        firstWifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(SSID));
-        WifiInfo secondWifiInfo = new WifiInfo();
-        firstWifiInfo.setSSID(WifiSsid.createFromAsciiEncoded("blah"));
-
-        mWifiWakeupNotificationHelper.maybeShowWifiEnabledNotification(WIFI_CONFIGURATION);
-
-        when(mWifiManager.isWifiEnabled()).thenReturn(true);
-        when(mWifiManager.getConnectionInfo()).thenReturn(firstWifiInfo, secondWifiInfo);
-
-        mWifiWakeupNotificationHelper.mBroadcastReceiver.onReceive(mContext,
-                new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
-
-        verify(mNotificationManager, never()).cancel(anyString(), anyInt());
-
-        mWifiWakeupNotificationHelper.mBroadcastReceiver.onReceive(mContext,
-                new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
-
-        verify(mNotificationManager).cancel(anyString(), anyInt());
-    }
-}
