diff --git a/service/java/com/android/server/wifi/WakeupEvaluator.java b/service/java/com/android/server/wifi/WakeupEvaluator.java
new file mode 100644
index 0000000..df9c43d
--- /dev/null
+++ b/service/java/com/android/server/wifi/WakeupEvaluator.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 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.server.wifi;
+
+import android.content.Context;
+import android.net.wifi.ScanResult;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.Collection;
+
+/**
+ * Evaluates ScanResults for Wifi Wake.
+ */
+public class WakeupEvaluator {
+
+    private final int mThresholdMinimumRssi24;
+    private final int mThresholdMinimumRssi5;
+
+    /**
+     * Constructs a {@link WakeupEvaluator} using the given context.
+     */
+    public static WakeupEvaluator fromContext(Context context) {
+        int minimumRssi24 = context.getResources().getInteger(
+                R.integer.config_wifi_framework_wifi_score_entry_rssi_threshold_24GHz);
+        int minimumRssi5 = context.getResources().getInteger(
+                R.integer.config_wifi_framework_wifi_score_entry_rssi_threshold_5GHz);
+        return new WakeupEvaluator(minimumRssi24, minimumRssi5);
+    }
+
+    @VisibleForTesting
+    WakeupEvaluator(int minimumRssi24, int minimumRssi5) {
+        mThresholdMinimumRssi24 = minimumRssi24;
+        mThresholdMinimumRssi5 = minimumRssi5;
+    }
+
+    /**
+     * Searches ScanResults to find a connectable network.
+     *
+     * <p>This method searches the given ScanResults for one that is present in the given
+     * ScanResultMatchInfos and has a sufficiently high RSSI. If there is no such ScanResult, it
+     * returns null. If there are multiple, it returns the one with the highest RSSI.
+     *
+     * @param scanResults ScanResults to search
+     * @param savedNetworks Network list to compare against
+     * @return The {@link ScanResult} representing an in-range connectable network, or {@code null}
+     *         signifying there is no viable network
+     */
+    public ScanResult findViableNetwork(Collection<ScanResult> scanResults,
+                                        Collection<ScanResultMatchInfo> savedNetworks) {
+        ScanResult selectedScanResult = null;
+
+        for (ScanResult scanResult : scanResults) {
+            if (isBelowThreshold(scanResult)) {
+                continue;
+            }
+            if (savedNetworks.contains(ScanResultMatchInfo.fromScanResult(scanResult))) {
+                if (selectedScanResult == null || selectedScanResult.level < scanResult.level) {
+                    selectedScanResult = scanResult;
+                }
+            }
+        }
+
+        return selectedScanResult;
+    }
+
+    /**
+     * Returns whether the given ScanResult's signal strength is below the selection threshold.
+     */
+    public boolean isBelowThreshold(ScanResult scanResult) {
+        return ((scanResult.is24GHz() && scanResult.level < mThresholdMinimumRssi24)
+                || (scanResult.is5GHz() && scanResult.level < mThresholdMinimumRssi5));
+    }
+}
diff --git a/tests/wifitests/src/com/android/server/wifi/WakeupEvaluatorTest.java b/tests/wifitests/src/com/android/server/wifi/WakeupEvaluatorTest.java
new file mode 100644
index 0000000..d975018
--- /dev/null
+++ b/tests/wifitests/src/com/android/server/wifi/WakeupEvaluatorTest.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 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.server.wifi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.net.wifi.ScanResult;
+import android.util.ArraySet;
+
+import com.android.server.wifi.util.ScanResultUtil;
+
+import com.google.android.collect.Sets;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.Set;
+
+
+
+/**
+ * Unit tests for {@link WakeupEvaluator}.
+ */
+public class WakeupEvaluatorTest {
+
+    private static final String SAVED_SSID_1 = "saved ssid 1";
+    private static final String SAVED_SSID_2 = "saved ssid 2";
+    private static final String UNSAVED_SSID = "unsaved ssid";
+
+    private static final int FREQ_24 = 2402;
+    private static final int FREQ_5 = 5000;
+
+    private static final int THRESHOLD_24 = -10;
+    private static final int THRESHOLD_5 = -1;
+
+    private WakeupEvaluator mWakeupEvaluator;
+
+    private ScanResult makeScanResult(String ssid, int frequency, int level) {
+        ScanResult scanResult = new ScanResult();
+        scanResult.SSID = ssid;
+        scanResult.frequency = frequency;
+        scanResult.level = level;
+        scanResult.capabilities = "[]";
+
+        return scanResult;
+    }
+
+    private Set<ScanResultMatchInfo> getSavedNetworks() {
+        Set<ScanResultMatchInfo> networks = new ArraySet<>();
+        networks.add(ScanResultMatchInfo.fromWifiConfiguration(
+                WifiConfigurationTestUtil.createOpenNetwork(
+                        ScanResultUtil.createQuotedSSID(SAVED_SSID_1))));
+        networks.add(ScanResultMatchInfo.fromWifiConfiguration(
+                WifiConfigurationTestUtil.createOpenNetwork(
+                        ScanResultUtil.createQuotedSSID(SAVED_SSID_2))));
+        return networks;
+    }
+
+    @Before
+    public void setUp() {
+        mWakeupEvaluator = new WakeupEvaluator(THRESHOLD_24, THRESHOLD_5);
+    }
+
+    /**
+     * Verify that isBelowThreshold returns true for networks below the filter threshold.
+     */
+    @Test
+    public void isBelowThreshold_returnsTrueWhenRssiIsBelowThreshold() {
+        ScanResult scanResult24 = makeScanResult(SAVED_SSID_1, FREQ_24, THRESHOLD_24 - 1);
+        assertTrue(mWakeupEvaluator.isBelowThreshold(scanResult24));
+
+        ScanResult scanResult5 = makeScanResult(SAVED_SSID_1, FREQ_5, THRESHOLD_5 - 1);
+        assertTrue(mWakeupEvaluator.isBelowThreshold(scanResult5));
+    }
+
+    /**
+     * Verify that isBelowThreshold returns false for networks above the filter threshold.
+     */
+    @Test
+    public void isBelowThreshold_returnsFalseWhenRssiIsAboveThreshold() {
+        ScanResult scanResult24 = makeScanResult(SAVED_SSID_1, FREQ_24, THRESHOLD_24 + 1);
+        assertFalse(mWakeupEvaluator.isBelowThreshold(scanResult24));
+
+        ScanResult scanResult5 = makeScanResult(SAVED_SSID_1, FREQ_5, THRESHOLD_5 + 1);
+        assertFalse(mWakeupEvaluator.isBelowThreshold(scanResult5));
+    }
+
+    /**
+     * Verify that findViableNetwork does not select ScanResult that is not present in the
+     * WifiConfigurations.
+     */
+    @Test
+    public void findViableNetwork_returnsNullWhenScanResultIsNotInSavedNetworks() {
+        Set<ScanResult> scanResults = Collections.singleton(
+                makeScanResult(UNSAVED_SSID, FREQ_24, THRESHOLD_24 + 1));
+
+        ScanResult scanResult = mWakeupEvaluator.findViableNetwork(scanResults, getSavedNetworks());
+
+        assertNull(scanResult);
+    }
+
+    /**
+     * Verify that findViableNetwork does not select a scan result that is below the threshold.
+     */
+    @Test
+    public void findViableNetwork_returnsNullWhenScanResultIsBelowThreshold() {
+        Set<ScanResult> scanResults = Collections.singleton(
+                makeScanResult(SAVED_SSID_1, FREQ_24, THRESHOLD_24 - 1));
+
+        ScanResult scanResult = mWakeupEvaluator.findViableNetwork(scanResults, getSavedNetworks());
+        assertNull(scanResult);
+    }
+
+    /**
+     * Verify that findViableNetwork returns a viable ScanResult.
+     */
+    @Test
+    public void findViableNetwork_returnsConnectableScanResult() {
+        ScanResult savedScanResult = makeScanResult(SAVED_SSID_1, FREQ_24, THRESHOLD_24 + 1);
+        Set<ScanResult> scanResults = Collections.singleton(savedScanResult);
+
+        ScanResult scanResult = mWakeupEvaluator.findViableNetwork(scanResults, getSavedNetworks());
+        assertEquals(savedScanResult, scanResult);
+    }
+
+    /**
+     * Verify that findViableNetwork returns the viable ScanResult with the highest RSSI.
+     */
+    @Test
+    public void findViableNetwork_returnsConnectableScanResultWithHighestRssi() {
+        ScanResult savedScanResultLow = makeScanResult(SAVED_SSID_1, FREQ_24, THRESHOLD_24 + 1);
+        ScanResult savedScanResultHigh = makeScanResult(SAVED_SSID_1, FREQ_24, THRESHOLD_24 + 10);
+        Set<ScanResult> scanResults = Sets.newArraySet(savedScanResultLow, savedScanResultHigh);
+
+        ScanResult scanResult = mWakeupEvaluator.findViableNetwork(scanResults, getSavedNetworks());
+        assertEquals(savedScanResultHigh, scanResult);
+    }
+}
