diff --git a/core/java/android/net/MacAddress.java b/core/java/android/net/MacAddress.java
index 98f3567..4cd0001 100644
--- a/core/java/android/net/MacAddress.java
+++ b/core/java/android/net/MacAddress.java
@@ -393,4 +393,19 @@
         }
         return out;
     }
+
+    /**
+     * Checks if this MAC Address matches the provided range.
+     *
+     * @param baseAddress MacAddress representing the base address to compare with.
+     * @param mask MacAddress representing the mask to use during comparison.
+     * @return true if this MAC Address matches the given range.
+     *
+     * @hide
+     */
+    public boolean matches(@NonNull MacAddress baseAddress, @NonNull MacAddress mask) {
+        Preconditions.checkNotNull(baseAddress);
+        Preconditions.checkNotNull(mask);
+        return (mAddr & mask.mAddr) == (baseAddress.mAddr & mask.mAddr);
+    }
 }
diff --git a/tests/net/java/android/net/MacAddressTest.java b/tests/net/java/android/net/MacAddressTest.java
index 04266c5..b9222a8 100644
--- a/tests/net/java/android/net/MacAddressTest.java
+++ b/tests/net/java/android/net/MacAddressTest.java
@@ -17,8 +17,8 @@
 package android.net;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import android.support.test.filters.SmallTest;
@@ -252,6 +252,39 @@
         }
     }
 
+    @Test
+    public void testMatches() {
+        // match 4 bytes prefix
+        assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
+                MacAddress.fromString("aa:bb:cc:dd:00:00"),
+                MacAddress.fromString("ff:ff:ff:ff:00:00")));
+
+        // match bytes 0,1,2 and 5
+        assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
+                MacAddress.fromString("aa:bb:cc:00:00:11"),
+                MacAddress.fromString("ff:ff:ff:00:00:ff")));
+
+        // match 34 bit prefix
+        assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
+                MacAddress.fromString("aa:bb:cc:dd:c0:00"),
+                MacAddress.fromString("ff:ff:ff:ff:c0:00")));
+
+        // fail to match 36 bit prefix
+        assertFalse(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
+                MacAddress.fromString("aa:bb:cc:dd:40:00"),
+                MacAddress.fromString("ff:ff:ff:ff:f0:00")));
+
+        // match all 6 bytes
+        assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
+                MacAddress.fromString("aa:bb:cc:dd:ee:11"),
+                MacAddress.fromString("ff:ff:ff:ff:ff:ff")));
+
+        // match none of 6 bytes
+        assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
+                MacAddress.fromString("00:00:00:00:00:00"),
+                MacAddress.fromString("00:00:00:00:00:00")));
+    }
+
     static byte[] toByteArray(int... in) {
         byte[] out = new byte[in.length];
         for (int i = 0; i < in.length; i++) {
diff --git a/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java
new file mode 100644
index 0000000..55fde4c
--- /dev/null
+++ b/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+import static com.android.internal.util.Preconditions.checkNotNull;
+import static com.android.internal.util.Preconditions.checkState;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.MacAddress;
+import android.net.MatchAllNetworkSpecifier;
+import android.net.NetworkAgent;
+import android.net.NetworkRequest;
+import android.net.NetworkSpecifier;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Network specifier object used by wifi's {@link android.net.NetworkAgent}.
+ * @hide
+ */
+public final class WifiNetworkAgentSpecifier extends NetworkSpecifier implements Parcelable {
+    /**
+     * Security credentials for the currently connected network.
+     */
+    private final WifiConfiguration mWifiConfiguration;
+
+    /**
+     * The UID of the app that requested a specific wifi network using {@link WifiNetworkSpecifier}.
+     *
+     * Will only be filled when the device connects to a wifi network as a result of a
+     * {@link NetworkRequest} with {@link WifiNetworkSpecifier}. Will be set to -1 if the device
+     * auto-connected to a wifi network.
+     */
+    private final int mOriginalRequestorUid;
+
+    public WifiNetworkAgentSpecifier(@NonNull WifiConfiguration wifiConfiguration,
+                                     int originalRequestorUid) {
+        checkNotNull(wifiConfiguration);
+
+        mWifiConfiguration = wifiConfiguration;
+        mOriginalRequestorUid = originalRequestorUid;
+    }
+
+    /**
+     * @hide
+     */
+    public static final Creator<WifiNetworkAgentSpecifier> CREATOR =
+            new Creator<WifiNetworkAgentSpecifier>() {
+                @Override
+                public WifiNetworkAgentSpecifier createFromParcel(@NonNull Parcel in) {
+                    WifiConfiguration wifiConfiguration = in.readParcelable(null);
+                    int originalRequestorUid = in.readInt();
+                    return new WifiNetworkAgentSpecifier(wifiConfiguration, originalRequestorUid);
+                }
+
+                @Override
+                public WifiNetworkAgentSpecifier[] newArray(int size) {
+                    return new WifiNetworkAgentSpecifier[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeParcelable(mWifiConfiguration, flags);
+        dest.writeInt(mOriginalRequestorUid);
+    }
+
+    @Override
+    public boolean satisfiedBy(@Nullable NetworkSpecifier other) {
+        if (this == other) {
+            return true;
+        }
+        // Any generic requests should be satisifed by a specific wifi network.
+        if (other == null || other instanceof MatchAllNetworkSpecifier) {
+            return true;
+        }
+        if (other instanceof WifiNetworkSpecifier) {
+            return satisfiesNetworkSpecifier((WifiNetworkSpecifier) other);
+        }
+        if (other instanceof WifiNetworkAgentSpecifier) {
+            throw new IllegalStateException("WifiNetworkAgentSpecifier instances should never be "
+                    + "compared");
+        }
+        return false;
+    }
+
+    /**
+     * Match {@link WifiNetworkSpecifier} in app's {@link NetworkRequest} with the
+     * {@link WifiNetworkAgentSpecifier} in wifi platform's {@link NetworkAgent}.
+     */
+    public boolean satisfiesNetworkSpecifier(@NonNull WifiNetworkSpecifier ns) {
+        // None of these should be null by construction.
+        // {@link WifiNetworkConfigBuilder} enforces non-null in {@link WifiNetworkSpecifier}.
+        // {@link WifiNetworkFactory} ensures non-null in {@link WifiNetworkAgentSpecifier}.
+        checkNotNull(ns);
+        checkNotNull(ns.ssidPatternMatcher);
+        checkNotNull(ns.bssidPatternMatcher);
+        checkNotNull(ns.wifiConfiguration.allowedKeyManagement);
+        checkNotNull(this.mWifiConfiguration.SSID);
+        checkNotNull(this.mWifiConfiguration.BSSID);
+        checkNotNull(this.mWifiConfiguration.allowedKeyManagement);
+
+        final String ssidWithQuotes = this.mWifiConfiguration.SSID;
+        checkState(ssidWithQuotes.startsWith("\"") && ssidWithQuotes.endsWith("\""));
+        final String ssidWithoutQuotes = ssidWithQuotes.substring(1, ssidWithQuotes.length() - 1);
+        if (!ns.ssidPatternMatcher.match(ssidWithoutQuotes)) {
+            return false;
+        }
+        final MacAddress bssid = MacAddress.fromString(this.mWifiConfiguration.BSSID);
+        final MacAddress matchBaseAddress = ns.bssidPatternMatcher.first;
+        final MacAddress matchMask = ns.bssidPatternMatcher.second;
+        if (!bssid.matches(matchBaseAddress, matchMask))  {
+            return false;
+        }
+        if (!ns.wifiConfiguration.allowedKeyManagement.equals(
+                this.mWifiConfiguration.allowedKeyManagement)) {
+            return false;
+        }
+        if (ns.requestorUid != this.mOriginalRequestorUid) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                mWifiConfiguration.SSID,
+                mWifiConfiguration.BSSID,
+                mWifiConfiguration.allowedKeyManagement,
+                mOriginalRequestorUid);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof WifiNetworkAgentSpecifier)) {
+            return false;
+        }
+        WifiNetworkAgentSpecifier lhs = (WifiNetworkAgentSpecifier) obj;
+        return Objects.equals(this.mWifiConfiguration.SSID, lhs.mWifiConfiguration.SSID)
+                && Objects.equals(this.mWifiConfiguration.BSSID, lhs.mWifiConfiguration.BSSID)
+                && Objects.equals(this.mWifiConfiguration.allowedKeyManagement,
+                    lhs.mWifiConfiguration.allowedKeyManagement)
+                && mOriginalRequestorUid == lhs.mOriginalRequestorUid;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("WifiNetworkAgentSpecifier [");
+        sb.append(", WifiConfiguration=").append(
+                mWifiConfiguration == null ? null : mWifiConfiguration.configKey())
+                .append(", mOriginalRequestorUid=").append(mOriginalRequestorUid)
+                .append("]");
+        return sb.toString();
+    }
+
+    @Override
+    public void assertValidFromUid(int requestorUid) {
+        throw new IllegalStateException("WifiNetworkAgentSpecifier should never be used "
+                + "for requests.");
+    }
+}
diff --git a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
index d3c6330..4348399b 100644
--- a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
+++ b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
@@ -121,6 +121,9 @@
         if (other == null || other instanceof MatchAllNetworkSpecifier) {
             return true;
         }
+        if (other instanceof WifiNetworkAgentSpecifier) {
+            return ((WifiNetworkAgentSpecifier) other).satisfiesNetworkSpecifier(this);
+        }
         // Specific requests are checked for equality although testing for equality of 2 patterns do
         // not make much sense!
         return equals(other);
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java
new file mode 100644
index 0000000..1b0007c
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java
@@ -0,0 +1,453 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.net.MacAddress;
+import android.net.MatchAllNetworkSpecifier;
+import android.net.NetworkRequest;
+import android.net.NetworkSpecifier;
+import android.os.Parcel;
+import android.os.PatternMatcher;
+import android.support.test.filters.SmallTest;
+import android.util.Pair;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link android.net.wifi.WifiNetworkAgentSpecifier}.
+ */
+@SmallTest
+public class WifiNetworkAgentSpecifierTest {
+    private static final int TEST_UID = 5;
+    private static final int TEST_UID_1 = 8;
+    private static final String TEST_SSID = "Test123";
+    private static final String TEST_SSID_PATTERN = "Test";
+    private static final String TEST_SSID_1 = "456test";
+    private static final String TEST_BSSID = "12:12:12:aa:0b:c0";
+    private static final String TEST_BSSID_OUI_BASE_ADDRESS = "12:12:12:00:00:00";
+    private static final String TEST_BSSID_OUI_MASK = "ff:ff:ff:00:00:00";
+    private static final String TEST_BSSID_1 = "aa:cc:12:aa:0b:c0";
+    private static final String TEST_PRESHARED_KEY = "\"Test123\"";
+
+    /**
+     * Validate that parcel marshalling/unmarshalling works
+     */
+    @Test
+    public void testWifiNetworkAgentSpecifierParcel() {
+        WifiNetworkAgentSpecifier specifier = createDefaultNetworkAgentSpecifier();
+
+        Parcel parcelW = Parcel.obtain();
+        specifier.writeToParcel(parcelW, 0);
+        byte[] bytes = parcelW.marshall();
+        parcelW.recycle();
+
+        Parcel parcelR = Parcel.obtain();
+        parcelR.unmarshall(bytes, 0, bytes.length);
+        parcelR.setDataPosition(0);
+        WifiNetworkAgentSpecifier parcelSpecifier =
+                WifiNetworkAgentSpecifier.CREATOR.createFromParcel(parcelR);
+
+        assertEquals(specifier, parcelSpecifier);
+    }
+
+    /**
+     * Validate that the NetworkAgentSpecifier cannot be used in a {@link NetworkRequest} by apps.
+     */
+    @Test(expected = IllegalStateException.class)
+    public void testWifiNetworkAgentSpecifierNotUsedInNetworkRequest() {
+        WifiNetworkAgentSpecifier specifier = createDefaultNetworkAgentSpecifier();
+
+        specifier.assertValidFromUid(TEST_UID);
+    }
+
+    /**
+     * Validate NetworkAgentSpecifier equals with itself.
+     * a) Create network agent specifier 1 for WPA_PSK network
+     * b) Create network agent specifier 2 with the same params as specifier 1.
+     * c) Ensure that the specifier 2 equals specifier 1.
+     */
+    @Test
+    public void testWifiNetworkAgentSpecifierEqualsSame() {
+        WifiNetworkAgentSpecifier specifier1 = createDefaultNetworkAgentSpecifier();
+        WifiNetworkAgentSpecifier specifier2 = createDefaultNetworkAgentSpecifier();
+
+        assertTrue(specifier2.equals(specifier1));
+    }
+
+    /**
+     * Validate NetworkAgentSpecifier equals between instances of {@link WifiNetworkAgentSpecifier}.
+     * a) Create network agent specifier 1 for WPA_PSK network
+     * b) Create network agent specifier 2 with different key mgmt params.
+     * c) Ensure that the specifier 2 does not equal specifier 1.
+     */
+    @Test
+    public void testWifiNetworkAgentSpecifierDoesNotEqualsWhenKeyMgmtDifferent() {
+        WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration();
+        WifiNetworkAgentSpecifier specifier1 =
+                new WifiNetworkAgentSpecifier(
+                        wifiConfiguration1,
+                        TEST_UID);
+
+        WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1);
+        wifiConfiguration2.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+        WifiNetworkAgentSpecifier specifier2 =
+                new WifiNetworkAgentSpecifier(
+                        wifiConfiguration2,
+                        TEST_UID);
+
+        assertFalse(specifier2.equals(specifier1));
+    }
+
+    /**
+     * Validate NetworkAgentSpecifier equals between instances of {@link WifiNetworkAgentSpecifier}.
+     * a) Create network agent specifier 1 for WPA_PSK network
+     * b) Create network agent specifier 2 with different SSID.
+     * c) Ensure that the specifier 2 does not equal specifier 1.
+     */
+    @Test
+    public void testWifiNetworkAgentSpecifierDoesNotSatisifyWhenSsidDifferent() {
+        WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration();
+        WifiNetworkAgentSpecifier specifier1 =
+                new WifiNetworkAgentSpecifier(
+                        wifiConfiguration1,
+                        TEST_UID);
+
+        WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1);
+        wifiConfiguration2.SSID = TEST_SSID_1;
+        WifiNetworkAgentSpecifier specifier2 =
+                new WifiNetworkAgentSpecifier(
+                        wifiConfiguration2,
+                        TEST_UID);
+
+        assertFalse(specifier2.equals(specifier1));
+    }
+
+    /**
+     * Validate NetworkAgentSpecifier equals between instances of {@link WifiNetworkAgentSpecifier}.
+     * a) Create network agent specifier 1 for WPA_PSK network
+     * b) Create network agent specifier 2 with different BSSID.
+     * c) Ensure that the specifier 2 does not equal specifier 1.
+     */
+    @Test
+    public void testWifiNetworkAgentSpecifierDoesNotSatisifyWhenBssidDifferent() {
+        WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration();
+        WifiNetworkAgentSpecifier specifier1 =
+                new WifiNetworkAgentSpecifier(
+                        wifiConfiguration1,
+                        TEST_UID);
+
+        WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1);
+        wifiConfiguration2.BSSID = TEST_BSSID_1;
+        WifiNetworkAgentSpecifier specifier2 =
+                new WifiNetworkAgentSpecifier(
+                        wifiConfiguration2,
+                        TEST_UID);
+
+        assertFalse(specifier2.equals(specifier1));
+    }
+
+    /**
+     * Validate NetworkAgentSpecifier matching.
+     * a) Create a network agent specifier for WPA_PSK network
+     * b) Ensure that the specifier matches {@code null} and {@link MatchAllNetworkSpecifier}
+     * specifiers.
+     */
+    @Test
+    public void testWifiNetworkAgentSpecifierSatisifiesNullAndAllMatch() {
+        WifiNetworkAgentSpecifier specifier = createDefaultNetworkAgentSpecifier();
+
+        assertTrue(specifier.satisfiedBy(null));
+        assertTrue(specifier.satisfiedBy(new MatchAllNetworkSpecifier()));
+    }
+
+    /**
+     * Validate NetworkAgentSpecifier matching with itself.
+     * a) Create network agent specifier 1 for WPA_PSK network
+     * b) Create network agent specifier 2 with the same params as specifier 1.
+     * c) Ensure that invoking {@link NetworkSpecifier#satisfiedBy(NetworkSpecifier)} on 2
+     * {@link WifiNetworkAgentSpecifier} throws an exception.
+     */
+    @Test(expected = IllegalStateException.class)
+    public void testWifiNetworkAgentSpecifierDoesNotSatisifySame() {
+        WifiNetworkAgentSpecifier specifier1 = createDefaultNetworkAgentSpecifier();
+        WifiNetworkAgentSpecifier specifier2 = createDefaultNetworkAgentSpecifier();
+
+        assertTrue(specifier2.satisfiedBy(specifier1));
+    }
+
+    /**
+     * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
+     * a) Create network agent specifier for WPA_PSK network
+     * b) Create network specifier with matching SSID pattern.
+     * c) Ensure that the agent specifier is satisfied by specifier.
+     */
+    @Test
+    public void
+            testWifiNetworkAgentSpecifierSatisfiesNetworkSpecifierWithSsidPattern() {
+        WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
+
+        PatternMatcher ssidPattern =
+                new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
+        Pair<MacAddress, MacAddress> bssidPattern =
+                Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS);
+        WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
+        wificonfigurationNetworkSpecifier.allowedKeyManagement
+                .set(WifiConfiguration.KeyMgmt.WPA_PSK);
+        WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
+                ssidPattern,
+                bssidPattern,
+                wificonfigurationNetworkSpecifier,
+                TEST_UID);
+
+        assertTrue(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier));
+        assertTrue(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier));
+    }
+
+    /**
+     * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
+     * a) Create network agent specifier for WPA_PSK network
+     * b) Create network specifier with matching BSSID pattern.
+     * c) Ensure that the agent specifier is satisfied by specifier.
+     */
+    @Test
+    public void
+            testWifiNetworkAgentSpecifierSatisfiesNetworkSpecifierWithBssidPattern() {
+        WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
+
+        PatternMatcher ssidPattern =
+                new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB);
+        Pair<MacAddress, MacAddress> bssidPattern =
+                Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+                        MacAddress.fromString(TEST_BSSID_OUI_MASK));
+        WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
+        wificonfigurationNetworkSpecifier.allowedKeyManagement
+                .set(WifiConfiguration.KeyMgmt.WPA_PSK);
+        WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
+                ssidPattern,
+                bssidPattern,
+                wificonfigurationNetworkSpecifier,
+                TEST_UID);
+
+        assertTrue(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier));
+        assertTrue(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier));
+    }
+
+    /**
+     * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
+     * a) Create network agent specifier for WPA_PSK network
+     * b) Create network specifier with matching SSID & BSSID pattern.
+     * c) Ensure that the agent specifier is satisfied by specifier.
+     */
+    @Test
+    public void
+            testWifiNetworkAgentSpecifierSatisfiesNetworkSpecifierWithSsidAndBssidPattern() {
+        WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
+
+        PatternMatcher ssidPattern =
+                new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
+        Pair<MacAddress, MacAddress> bssidPattern =
+                Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+                        MacAddress.fromString(TEST_BSSID_OUI_MASK));
+        WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
+        wificonfigurationNetworkSpecifier.allowedKeyManagement
+                .set(WifiConfiguration.KeyMgmt.WPA_PSK);
+        WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
+                ssidPattern,
+                bssidPattern,
+                wificonfigurationNetworkSpecifier,
+                TEST_UID);
+
+        assertTrue(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier));
+        assertTrue(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier));
+    }
+
+    /**
+     * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
+     * a) Create network agent specifier for WPA_PSK network
+     * b) Create network specifier with non-matching SSID pattern.
+     * c) Ensure that the agent specifier is not satisfied by specifier.
+     */
+    @Test
+    public void
+            testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithSsidPattern() {
+        WifiConfiguration wifiConfigurationNetworkAgent = createDefaultWifiConfiguration();
+        wifiConfigurationNetworkAgent.SSID = "\"" + TEST_SSID_1 + "\"";
+        WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier =
+                new WifiNetworkAgentSpecifier(
+                        wifiConfigurationNetworkAgent,
+                        TEST_UID);
+
+        PatternMatcher ssidPattern =
+                new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
+        Pair<MacAddress, MacAddress> bssidPattern =
+                Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS);
+        WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
+        wificonfigurationNetworkSpecifier.allowedKeyManagement
+                .set(WifiConfiguration.KeyMgmt.WPA_PSK);
+        WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
+                ssidPattern,
+                bssidPattern,
+                wificonfigurationNetworkSpecifier,
+                TEST_UID);
+
+        assertFalse(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier));
+        assertFalse(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier));
+    }
+
+    /**
+     * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
+     * a) Create network agent specifier for WPA_PSK network
+     * b) Create network specifier with non-matching BSSID pattern.
+     * c) Ensure that the agent specifier is not satisfied by specifier.
+     */
+    @Test
+    public void
+            testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithBssidPattern() {
+        WifiConfiguration wifiConfigurationNetworkAgent = createDefaultWifiConfiguration();
+        wifiConfigurationNetworkAgent.BSSID = TEST_BSSID_1;
+        WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier =
+                new WifiNetworkAgentSpecifier(
+                        wifiConfigurationNetworkAgent,
+                        TEST_UID);
+
+        PatternMatcher ssidPattern =
+                new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB);
+        Pair<MacAddress, MacAddress> bssidPattern =
+                Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+                        MacAddress.fromString(TEST_BSSID_OUI_MASK));
+        WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
+        wificonfigurationNetworkSpecifier.allowedKeyManagement
+                .set(WifiConfiguration.KeyMgmt.WPA_PSK);
+        WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
+                ssidPattern,
+                bssidPattern,
+                wificonfigurationNetworkSpecifier,
+                TEST_UID);
+
+        assertFalse(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier));
+        assertFalse(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier));
+    }
+
+    /**
+     * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
+     * a) Create network agent specifier for WPA_PSK network
+     * b) Create network specifier with non-matching SSID and BSSID pattern.
+     * c) Ensure that the agent specifier is not satisfied by specifier.
+     */
+    @Test
+    public void
+            testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithSsidAndBssidPattern() {
+        WifiConfiguration wifiConfigurationNetworkAgent = createDefaultWifiConfiguration();
+        wifiConfigurationNetworkAgent.BSSID = TEST_BSSID_1;
+        WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier =
+                new WifiNetworkAgentSpecifier(
+                        wifiConfigurationNetworkAgent,
+                        TEST_UID);
+
+        PatternMatcher ssidPattern =
+                new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
+        Pair<MacAddress, MacAddress> bssidPattern =
+                Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+                        MacAddress.fromString(TEST_BSSID_OUI_MASK));
+        WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
+        wificonfigurationNetworkSpecifier.allowedKeyManagement
+                .set(WifiConfiguration.KeyMgmt.WPA_PSK);
+        WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
+                ssidPattern,
+                bssidPattern,
+                wificonfigurationNetworkSpecifier,
+                TEST_UID);
+
+        assertFalse(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier));
+        assertFalse(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier));
+    }
+
+    /**
+     * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
+     * a) Create network agent specifier for WPA_PSK network
+     * b) Create network specifier with matching SSID and BSSID pattern, but different key mgmt.
+     * c) Ensure that the agent specifier is not satisfied by specifier.
+     */
+    @Test
+    public void
+            testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithDifferentKeyMgmt() {
+        WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
+
+        PatternMatcher ssidPattern =
+                new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
+        Pair<MacAddress, MacAddress> bssidPattern =
+                Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+                        MacAddress.fromString(TEST_BSSID_OUI_MASK));
+        WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
+        wificonfigurationNetworkSpecifier.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+        WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
+                ssidPattern,
+                bssidPattern,
+                wificonfigurationNetworkSpecifier,
+                TEST_UID);
+
+        assertFalse(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier));
+        assertFalse(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier));
+    }
+
+    /**
+     * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
+     * a) Create network agent specifier for WPA_PSK network
+     * b) Create network specifier with matching SSID and BSSID pattern, but different UID.
+     * c) Ensure that the agent specifier is not satisfied by specifier.
+     */
+    @Test
+    public void
+            testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithDifferentUid() {
+        WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
+
+        PatternMatcher ssidPattern =
+                new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
+        Pair<MacAddress, MacAddress> bssidPattern =
+                Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+                        MacAddress.fromString(TEST_BSSID_OUI_MASK));
+        WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
+        wificonfigurationNetworkSpecifier.allowedKeyManagement
+                .set(WifiConfiguration.KeyMgmt.WPA_PSK);
+        WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
+                ssidPattern,
+                bssidPattern,
+                wificonfigurationNetworkSpecifier,
+                TEST_UID_1);
+
+        assertFalse(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier));
+        assertFalse(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier));
+    }
+
+    private WifiConfiguration createDefaultWifiConfiguration() {
+        WifiConfiguration wifiConfiguration = new WifiConfiguration();
+        wifiConfiguration.SSID = "\"" + TEST_SSID + "\"";
+        wifiConfiguration.BSSID = TEST_BSSID;
+        wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+        wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
+        return wifiConfiguration;
+    }
+
+    private WifiNetworkAgentSpecifier createDefaultNetworkAgentSpecifier() {
+        return new WifiNetworkAgentSpecifier(createDefaultWifiConfiguration(), TEST_UID);
+    }
+
+}
