Merge changes from topic 'ipsec-hide-overloads'

* changes:
  Hide Socket+DatagramSocket IpSecTransform methods
  Consistenly Throw IOExceptions from IpSecManager
diff --git a/api/current.txt b/api/current.txt
index 19febb7..883d986 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -25120,8 +25120,8 @@
   }
 
   public class DiscoverySession {
-    method public java.lang.String createNetworkSpecifierOpen(android.net.wifi.aware.PeerHandle);
-    method public java.lang.String createNetworkSpecifierPassphrase(android.net.wifi.aware.PeerHandle, java.lang.String);
+    method public android.net.NetworkSpecifier createNetworkSpecifierOpen(android.net.wifi.aware.PeerHandle);
+    method public android.net.NetworkSpecifier createNetworkSpecifierPassphrase(android.net.wifi.aware.PeerHandle, java.lang.String);
     method public void destroy();
     method public void sendMessage(android.net.wifi.aware.PeerHandle, int, byte[]);
   }
@@ -25207,8 +25207,8 @@
   }
 
   public class WifiAwareSession {
-    method public java.lang.String createNetworkSpecifierOpen(int, byte[]);
-    method public java.lang.String createNetworkSpecifierPassphrase(int, byte[], java.lang.String);
+    method public android.net.NetworkSpecifier createNetworkSpecifierOpen(int, byte[]);
+    method public android.net.NetworkSpecifier createNetworkSpecifierPassphrase(int, byte[], java.lang.String);
     method public void destroy();
     method public void publish(android.net.wifi.aware.PublishConfig, android.net.wifi.aware.DiscoverySessionCallback, android.os.Handler);
     method public void subscribe(android.net.wifi.aware.SubscribeConfig, android.net.wifi.aware.DiscoverySessionCallback, android.os.Handler);
diff --git a/api/system-current.txt b/api/system-current.txt
index 452ab25..3b61bdd 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -27676,9 +27676,9 @@
   }
 
   public class DiscoverySession {
-    method public java.lang.String createNetworkSpecifierOpen(android.net.wifi.aware.PeerHandle);
-    method public java.lang.String createNetworkSpecifierPassphrase(android.net.wifi.aware.PeerHandle, java.lang.String);
-    method public java.lang.String createNetworkSpecifierPmk(android.net.wifi.aware.PeerHandle, byte[]);
+    method public android.net.NetworkSpecifier createNetworkSpecifierOpen(android.net.wifi.aware.PeerHandle);
+    method public android.net.NetworkSpecifier createNetworkSpecifierPassphrase(android.net.wifi.aware.PeerHandle, java.lang.String);
+    method public android.net.NetworkSpecifier createNetworkSpecifierPmk(android.net.wifi.aware.PeerHandle, byte[]);
     method public void destroy();
     method public void sendMessage(android.net.wifi.aware.PeerHandle, int, byte[]);
   }
@@ -27764,9 +27764,9 @@
   }
 
   public class WifiAwareSession {
-    method public java.lang.String createNetworkSpecifierOpen(int, byte[]);
-    method public java.lang.String createNetworkSpecifierPassphrase(int, byte[], java.lang.String);
-    method public java.lang.String createNetworkSpecifierPmk(int, byte[], byte[]);
+    method public android.net.NetworkSpecifier createNetworkSpecifierOpen(int, byte[]);
+    method public android.net.NetworkSpecifier createNetworkSpecifierPassphrase(int, byte[], java.lang.String);
+    method public android.net.NetworkSpecifier createNetworkSpecifierPmk(int, byte[], byte[]);
     method public void destroy();
     method public void publish(android.net.wifi.aware.PublishConfig, android.net.wifi.aware.DiscoverySessionCallback, android.os.Handler);
     method public void subscribe(android.net.wifi.aware.SubscribeConfig, android.net.wifi.aware.DiscoverySessionCallback, android.os.Handler);
diff --git a/api/test-current.txt b/api/test-current.txt
index ad15b20..61a65d8 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -25194,8 +25194,8 @@
   }
 
   public class DiscoverySession {
-    method public java.lang.String createNetworkSpecifierOpen(android.net.wifi.aware.PeerHandle);
-    method public java.lang.String createNetworkSpecifierPassphrase(android.net.wifi.aware.PeerHandle, java.lang.String);
+    method public android.net.NetworkSpecifier createNetworkSpecifierOpen(android.net.wifi.aware.PeerHandle);
+    method public android.net.NetworkSpecifier createNetworkSpecifierPassphrase(android.net.wifi.aware.PeerHandle, java.lang.String);
     method public void destroy();
     method public void sendMessage(android.net.wifi.aware.PeerHandle, int, byte[]);
   }
@@ -25281,8 +25281,8 @@
   }
 
   public class WifiAwareSession {
-    method public java.lang.String createNetworkSpecifierOpen(int, byte[]);
-    method public java.lang.String createNetworkSpecifierPassphrase(int, byte[], java.lang.String);
+    method public android.net.NetworkSpecifier createNetworkSpecifierOpen(int, byte[]);
+    method public android.net.NetworkSpecifier createNetworkSpecifierPassphrase(int, byte[], java.lang.String);
     method public void destroy();
     method public void publish(android.net.wifi.aware.PublishConfig, android.net.wifi.aware.DiscoverySessionCallback, android.os.Handler);
     method public void subscribe(android.net.wifi.aware.SubscribeConfig, android.net.wifi.aware.DiscoverySessionCallback, android.os.Handler);
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
index 1ffa864..601ed01 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
@@ -78,7 +78,6 @@
     public static final int CMD_IPV6_TETHER_UPDATE          = BASE_IFACE + 13;
 
     private final State mInitialState;
-    private final State mServingState;
     private final State mLocalHotspotState;
     private final State mTetheredState;
     private final State mUnavailableState;
@@ -107,14 +106,12 @@
         mLastError = ConnectivityManager.TETHER_ERROR_NO_ERROR;
 
         mInitialState = new InitialState();
-        mServingState = new ServingState();
         mLocalHotspotState = new LocalHotspotState();
         mTetheredState = new TetheredState();
         mUnavailableState = new UnavailableState();
         addState(mInitialState);
-        addState(mServingState);
-            addState(mLocalHotspotState, mServingState);
-            addState(mTetheredState, mServingState);
+        addState(mLocalHotspotState);
+        addState(mTetheredState);
         addState(mUnavailableState);
 
         setInitialState(mInitialState);
@@ -222,12 +219,11 @@
         }
     }
 
-    class ServingState extends State {
+    class BaseServingState extends State {
         @Override
         public void enter() {
             if (!configureIfaceIp(true)) {
                 mLastError = ConnectivityManager.TETHER_ERROR_IFACE_CFG_ERROR;
-                transitionTo(mInitialState);
                 return;
             }
 
@@ -236,12 +232,13 @@
             } catch (Exception e) {
                 Log.e(TAG, "Error Tethering: " + e.toString());
                 mLastError = ConnectivityManager.TETHER_ERROR_TETHER_IFACE_ERROR;
-                transitionTo(mInitialState);
                 return;
             }
 
             if (!mIPv6TetherSvc.start()) {
                 Log.e(TAG, "Failed to start IPv6TetheringInterfaceServices");
+                // TODO: Make this a fatal error once Bluetooth IPv6 is sorted.
+                return;
             }
         }
 
@@ -254,9 +251,9 @@
 
             try {
                 mNMService.untetherInterface(mIfaceName);
-            } catch (Exception ee) {
+            } catch (Exception e) {
                 mLastError = ConnectivityManager.TETHER_ERROR_UNTETHER_IFACE_ERROR;
-                Log.e(TAG, "Failed to untether interface: " + ee.toString());
+                Log.e(TAG, "Failed to untether interface: " + e.toString());
             }
 
             configureIfaceIp(false);
@@ -293,15 +290,27 @@
         }
     }
 
-    class LocalHotspotState extends State {
+    // Handling errors in BaseServingState.enter() by transitioning is
+    // problematic because transitioning during a multi-state jump yields
+    // a Log.wtf(). Ultimately, there should be only one ServingState,
+    // and forwarding and NAT rules should be handled by a coordinating
+    // functional element outside of TetherInterfaceStateMachine.
+    class LocalHotspotState extends BaseServingState {
         @Override
         public void enter() {
+            super.enter();
+            if (mLastError != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
+                transitionTo(mInitialState);
+            }
+
             if (DBG) Log.d(TAG, "Local hotspot " + mIfaceName);
             sendInterfaceState(IControlsTethering.STATE_LOCAL_HOTSPOT);
         }
 
         @Override
         public boolean processMessage(Message message) {
+            if (super.processMessage(message)) return true;
+
             maybeLogMessage(this, message.what);
             switch (message.what) {
                 case CMD_TETHER_REQUESTED:
@@ -317,9 +326,19 @@
         }
     }
 
-    class TetheredState extends State {
+    // Handling errors in BaseServingState.enter() by transitioning is
+    // problematic because transitioning during a multi-state jump yields
+    // a Log.wtf(). Ultimately, there should be only one ServingState,
+    // and forwarding and NAT rules should be handled by a coordinating
+    // functional element outside of TetherInterfaceStateMachine.
+    class TetheredState extends BaseServingState {
         @Override
         public void enter() {
+            super.enter();
+            if (mLastError != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
+                transitionTo(mInitialState);
+            }
+
             if (DBG) Log.d(TAG, "Tethered " + mIfaceName);
             sendInterfaceState(IControlsTethering.STATE_TETHERED);
         }
@@ -327,6 +346,7 @@
         @Override
         public void exit() {
             cleanupUpstream();
+            super.exit();
         }
 
         private void cleanupUpstream() {
@@ -361,6 +381,8 @@
 
         @Override
         public boolean processMessage(Message message) {
+            if (super.processMessage(message)) return true;
+
             maybeLogMessage(this, message.what);
             boolean retValue = true;
             switch (message.what) {
diff --git a/wifi/java/android/net/wifi/aware/DiscoverySession.java b/wifi/java/android/net/wifi/aware/DiscoverySession.java
index 82b3792..bf5c42b8 100644
--- a/wifi/java/android/net/wifi/aware/DiscoverySession.java
+++ b/wifi/java/android/net/wifi/aware/DiscoverySession.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.net.NetworkSpecifier;
 import android.net.wifi.RttManager;
 import android.util.Log;
 
@@ -250,8 +251,8 @@
     }
 
     /**
-     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} for an
-     * unencrypted WiFi Aware connection (link) to the specified peer. The
+     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} for
+     * an unencrypted WiFi Aware connection (link) to the specified peer. The
      * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
      * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
      * <p>
@@ -276,13 +277,13 @@
      *                   request from only that peer. A RESPONDER may specify a {@code null} -
      *                   indicating that it will accept connection requests from any device.
      *
-     * @return A string to be used to construct
-     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
+     * @return A {@link NetworkSpecifier} to be used to construct
+     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass to
      * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
      * android.net.ConnectivityManager.NetworkCallback)}
      * [or other varieties of that API].
      */
-    public String createNetworkSpecifierOpen(@Nullable PeerHandle peerHandle) {
+    public NetworkSpecifier createNetworkSpecifierOpen(@Nullable PeerHandle peerHandle) {
         if (mTerminated) {
             Log.w(TAG, "createNetworkSpecifierOpen: called on terminated session");
             return null;
@@ -302,8 +303,8 @@
     }
 
     /**
-     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} for an
-     * encrypted WiFi Aware connection (link) to the specified peer. The
+     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} for
+     * an encrypted WiFi Aware connection (link) to the specified peer. The
      * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
      * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
      * <p>
@@ -329,14 +330,14 @@
      *                   {@link #createNetworkSpecifierOpen(PeerHandle)} API to
      *                   specify an open (unencrypted) link.
      *
-     * @return A string to be used to construct
-     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
+     * @return A {@link NetworkSpecifier} to be used to construct
+     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass to
      * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
      * android.net.ConnectivityManager.NetworkCallback)}
      * [or other varieties of that API].
      */
-    public String createNetworkSpecifierPassphrase(@Nullable PeerHandle peerHandle,
-            @NonNull String passphrase) {
+    public NetworkSpecifier createNetworkSpecifierPassphrase(
+            @Nullable PeerHandle peerHandle, @NonNull String passphrase) {
         if (passphrase == null || passphrase.length() == 0) {
             throw new IllegalArgumentException("Passphrase must not be null or empty");
         }
@@ -361,8 +362,8 @@
     }
 
     /**
-     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} for an
-     * encrypted WiFi Aware connection (link) to the specified peer. The
+     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} for
+     * an encrypted WiFi Aware connection (link) to the specified peer. The
      * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
      * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
      * <p>
@@ -389,8 +390,8 @@
      *            Passphrase or {@link #createNetworkSpecifierOpen(PeerHandle)} to specify an
      *            open (unencrypted) link.
      *
-     * @return A string to be used to construct
-     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
+     * @return A {@link NetworkSpecifier} to be used to construct
+     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass to
      * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
      * android.net.ConnectivityManager.NetworkCallback)}
      * [or other varieties of that API].
@@ -398,7 +399,7 @@
      * @hide
      */
     @SystemApi
-    public String createNetworkSpecifierPmk(@Nullable PeerHandle peerHandle,
+    public NetworkSpecifier createNetworkSpecifierPmk(@Nullable PeerHandle peerHandle,
             @NonNull byte[] pmk) {
         if (pmk == null || pmk.length == 0) {
             throw new IllegalArgumentException("PMK must not be null or empty");
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
index 4d3957a..3fcbd4b 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
@@ -24,6 +24,7 @@
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.NetworkRequest;
+import android.net.NetworkSpecifier;
 import android.net.wifi.RttManager;
 import android.os.Binder;
 import android.os.Bundle;
@@ -31,7 +32,6 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
-import android.util.Base64;
 import android.util.Log;
 import android.util.SparseArray;
 
@@ -39,9 +39,6 @@
 
 import libcore.util.HexEncoding;
 
-import org.json.JSONException;
-import org.json.JSONObject;
-
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.ref.WeakReference;
@@ -129,65 +126,6 @@
     private static final boolean VDBG = false; // STOPSHIP if true
 
     /**
-     * Keys used to generate a Network Specifier for the Aware network request. The network
-     * specifier is formatted as a JSON string.
-     */
-
-    /**
-     * TYPE: in band, specific peer: role, client_id, session_id, peer_id, pmk/passphrase optional
-     * @hide
-     */
-    public static final int NETWORK_SPECIFIER_TYPE_IB = 0;
-
-    /**
-     * TYPE: in band, any peer: role, client_id, session_id, pmk/passphrase optional
-     * [only permitted for RESPONDER]
-     * @hide
-     */
-    public static final int NETWORK_SPECIFIER_TYPE_IB_ANY_PEER = 1;
-
-    /**
-     * TYPE: out-of-band: role, client_id, peer_mac, pmk/passphrase optional
-     * @hide
-     */
-    public static final int NETWORK_SPECIFIER_TYPE_OOB = 2;
-
-    /**
-     * TYPE: out-of-band, any peer: role, client_id, pmk/passphrase optional
-     * [only permitted for RESPONDER]
-     * @hide
-     */
-    public static final int NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER = 3;
-
-
-    /** @hide */
-    public static final int NETWORK_SPECIFIER_TYPE_MAX_VALID = NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER;
-
-    /** @hide */
-    public static final String NETWORK_SPECIFIER_KEY_TYPE = "type";
-
-    /** @hide */
-    public static final String NETWORK_SPECIFIER_KEY_ROLE = "role";
-
-    /** @hide */
-    public static final String NETWORK_SPECIFIER_KEY_CLIENT_ID = "client_id";
-
-    /** @hide */
-    public static final String NETWORK_SPECIFIER_KEY_SESSION_ID = "session_id";
-
-    /** @hide */
-    public static final String NETWORK_SPECIFIER_KEY_PEER_ID = "peer_id";
-
-    /** @hide */
-    public static final String NETWORK_SPECIFIER_KEY_PEER_MAC = "peer_mac";
-
-    /** @hide */
-    public static final String NETWORK_SPECIFIER_KEY_PMK = "pmk";
-
-    /** @hide */
-    public static final String NETWORK_SPECIFIER_KEY_PASSPHRASE = "passphrase";
-
-    /**
      * Broadcast intent action to indicate that the state of Wi-Fi Aware availability has changed.
      * Use the {@link #isAvailable()} to query the current status.
      * This broadcast is <b>not</b> sticky, use the {@link #isAvailable()} API after registering
@@ -483,7 +421,7 @@
     }
 
     /** @hide */
-    public String createNetworkSpecifier(int clientId, int role, int sessionId,
+    public NetworkSpecifier createNetworkSpecifier(int clientId, int role, int sessionId,
             PeerHandle peerHandle, @Nullable byte[] pmk, @Nullable String passphrase) {
         if (VDBG) {
             Log.v(TAG, "createNetworkSpecifier: role=" + role + ", sessionId=" + sessionId
@@ -492,9 +430,6 @@
                     + ", passphrase=" + ((passphrase == null) ? "null" : "non-null"));
         }
 
-        int type = (peerHandle == null) ? NETWORK_SPECIFIER_TYPE_IB_ANY_PEER
-                : NETWORK_SPECIFIER_TYPE_IB;
-
         if (role != WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
                 && role != WIFI_AWARE_DATA_PATH_ROLE_RESPONDER) {
             throw new IllegalArgumentException(
@@ -509,35 +444,20 @@
             }
         }
 
-        JSONObject json;
-        try {
-            json = new JSONObject();
-            json.put(NETWORK_SPECIFIER_KEY_TYPE, type);
-            json.put(NETWORK_SPECIFIER_KEY_ROLE, role);
-            json.put(NETWORK_SPECIFIER_KEY_CLIENT_ID, clientId);
-            json.put(NETWORK_SPECIFIER_KEY_SESSION_ID, sessionId);
-            if (peerHandle != null) {
-                json.put(NETWORK_SPECIFIER_KEY_PEER_ID, peerHandle.peerId);
-            }
-            if (pmk == null) {
-                pmk = new byte[0];
-            }
-            json.put(NETWORK_SPECIFIER_KEY_PMK,
-                    Base64.encodeToString(pmk, 0, pmk.length, Base64.DEFAULT));
-            if (passphrase == null) {
-                passphrase = new String();
-            }
-            json.put(NETWORK_SPECIFIER_KEY_PASSPHRASE, passphrase);
-
-        } catch (JSONException e) {
-            return "";
-        }
-
-        return json.toString();
+        return new WifiAwareNetworkSpecifier(
+                (peerHandle == null) ? WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB_ANY_PEER
+                        : WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB,
+                role,
+                clientId,
+                sessionId,
+                peerHandle != null ? peerHandle.peerId : 0, // 0 is an invalid peer ID
+                null, // peerMac (not used in this method)
+                pmk,
+                passphrase);
     }
 
     /** @hide */
-    public String createNetworkSpecifier(int clientId, @DataPathRole int role,
+    public NetworkSpecifier createNetworkSpecifier(int clientId, @DataPathRole int role,
             @Nullable byte[] peer, @Nullable byte[] pmk, @Nullable String passphrase) {
         if (VDBG) {
             Log.v(TAG, "createNetworkSpecifier: role=" + role
@@ -545,9 +465,6 @@
                     + ", passphrase=" + ((passphrase == null) ? "null" : "non-null"));
         }
 
-        int type = (peer == null) ?
-                NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER : NETWORK_SPECIFIER_TYPE_OOB;
-
         if (role != WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
                 && role != WIFI_AWARE_DATA_PATH_ROLE_RESPONDER) {
             throw new IllegalArgumentException(
@@ -564,29 +481,16 @@
             throw new IllegalArgumentException("createNetworkSpecifier: Invalid peer MAC address");
         }
 
-        JSONObject json;
-        try {
-            json = new JSONObject();
-            json.put(NETWORK_SPECIFIER_KEY_TYPE, type);
-            json.put(NETWORK_SPECIFIER_KEY_ROLE, role);
-            json.put(NETWORK_SPECIFIER_KEY_CLIENT_ID, clientId);
-            if (peer != null) {
-                json.put(NETWORK_SPECIFIER_KEY_PEER_MAC, new String(HexEncoding.encode(peer)));
-            }
-            if (pmk == null) {
-                pmk = new byte[0];
-            }
-            json.put(NETWORK_SPECIFIER_KEY_PMK,
-                    Base64.encodeToString(pmk, 0, pmk.length, Base64.DEFAULT));
-            if (passphrase == null) {
-                passphrase = new String();
-            }
-            json.put(NETWORK_SPECIFIER_KEY_PASSPHRASE, passphrase);
-        } catch (JSONException e) {
-            return "";
-        }
-
-        return json.toString();
+        return new WifiAwareNetworkSpecifier(
+                (peer == null) ? WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER
+                        : WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB,
+                role,
+                clientId,
+                0, // 0 is an invalid session ID
+                0, // 0 is an invalid peer ID
+                peer,
+                pmk,
+                passphrase);
     }
 
     private static class WifiAwareEventCallbackProxy extends IWifiAwareEventCallback.Stub {
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
new file mode 100644
index 0000000..5993480
--- /dev/null
+++ b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
@@ -0,0 +1,234 @@
+/*
+ * 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 android.net.wifi.aware;
+
+import android.net.NetworkSpecifier;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * Network specifier object used to request a Wi-Fi Aware network. Apps do not create these objects
+ * directly but obtain them using
+ * {@link WifiAwareSession#createNetworkSpecifierOpen(int, byte[])} or
+ * {@link DiscoverySession#createNetworkSpecifierOpen(PeerHandle)} or their secure (Passphrase)
+ * versions.
+ *
+ * @hide
+ */
+public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements Parcelable {
+    /**
+     * TYPE: in band, specific peer: role, client_id, session_id, peer_id, pmk/passphrase optional
+     * @hide
+     */
+    public static final int NETWORK_SPECIFIER_TYPE_IB = 0;
+
+    /**
+     * TYPE: in band, any peer: role, client_id, session_id, pmk/passphrase optional
+     * [only permitted for RESPONDER]
+     * @hide
+     */
+    public static final int NETWORK_SPECIFIER_TYPE_IB_ANY_PEER = 1;
+
+    /**
+     * TYPE: out-of-band: role, client_id, peer_mac, pmk/passphrase optional
+     * @hide
+     */
+    public static final int NETWORK_SPECIFIER_TYPE_OOB = 2;
+
+    /**
+     * TYPE: out-of-band, any peer: role, client_id, pmk/passphrase optional
+     * [only permitted for RESPONDER]
+     * @hide
+     */
+    public static final int NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER = 3;
+
+    /** @hide */
+    public static final int NETWORK_SPECIFIER_TYPE_MAX_VALID = NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER;
+
+    /**
+     * One of the NETWORK_SPECIFIER_TYPE_* constants. The type of the network specifier object.
+     * @hide
+     */
+    public final int type;
+
+    /**
+     * The role of the device: WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR or
+     * WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER.
+     * @hide
+     */
+    public final int role;
+
+    /**
+     * The client ID of the device.
+     * @hide
+     */
+    public final int clientId;
+
+    /**
+     * The session ID in which context to request a data-path. Only relevant for IB requests.
+     * @hide
+     */
+    public final int sessionId;
+
+    /**
+     * The peer ID of the device which the data-path should be connected to. Only relevant for
+     * IB requests (i.e. not IB_ANY_PEER or OOB*).
+     * @hide
+     */
+    public final int peerId;
+
+    /**
+     * The peer MAC address of the device which the data-path should be connected to. Only relevant
+     * for OB requests (i.e. not OOB_ANY_PEER or IB*).
+     * @hide
+     */
+    public final byte[] peerMac;
+
+    /**
+     * The PMK of the requested data-path. Can be null. Only one or none of pmk or passphrase should
+     * be specified.
+     * @hide
+     */
+    public final byte[] pmk;
+
+    /**
+     * The Passphrase of the requested data-path. Can be null. Only one or none of the pmk or
+     * passphrase should be specified.
+     * @hide
+     */
+    public final String passphrase;
+
+    /** @hide */
+    public WifiAwareNetworkSpecifier(int type, int role, int clientId, int sessionId, int peerId,
+            byte[] peerMac, byte[] pmk, String passphrase) {
+        this.type = type;
+        this.role = role;
+        this.clientId = clientId;
+        this.sessionId = sessionId;
+        this.peerId = peerId;
+        this.peerMac = peerMac;
+        this.pmk = pmk;
+        this.passphrase = passphrase;
+    }
+
+    public static final Creator<WifiAwareNetworkSpecifier> CREATOR =
+            new Creator<WifiAwareNetworkSpecifier>() {
+                @Override
+                public WifiAwareNetworkSpecifier createFromParcel(Parcel in) {
+                    return new WifiAwareNetworkSpecifier(
+                        in.readInt(), // type
+                        in.readInt(), // role
+                        in.readInt(), // clientId
+                        in.readInt(), // sessionId
+                        in.readInt(), // peerId
+                        in.createByteArray(), // peerMac
+                        in.createByteArray(), // pmk
+                        in.readString()); // passphrase
+                }
+
+                @Override
+                public WifiAwareNetworkSpecifier[] newArray(int size) {
+                    return new WifiAwareNetworkSpecifier[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(type);
+        dest.writeInt(role);
+        dest.writeInt(clientId);
+        dest.writeInt(sessionId);
+        dest.writeInt(peerId);
+        dest.writeByteArray(peerMac);
+        dest.writeByteArray(pmk);
+        dest.writeString(passphrase);
+    }
+
+    /** @hide */
+    @Override
+    public boolean satisfiedBy(NetworkSpecifier other) {
+        // MatchAllNetworkSpecifier is taken care in NetworkCapabilities#satisfiedBySpecifier.
+        return equals(other);
+    }
+
+    /** @hide */
+    @Override
+    public int hashCode() {
+        int result = 17;
+
+        result = 31 * result + type;
+        result = 31 * result + role;
+        result = 31 * result + clientId;
+        result = 31 * result + sessionId;
+        result = 31 * result + peerId;
+        result = 31 * result + Arrays.hashCode(peerMac);
+        result = 31 * result + Arrays.hashCode(pmk);
+        result = 31 * result + Objects.hashCode(passphrase);
+
+        return result;
+    }
+
+    /** @hide */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (!(obj instanceof WifiAwareNetworkSpecifier)) {
+            return false;
+        }
+
+        WifiAwareNetworkSpecifier lhs = (WifiAwareNetworkSpecifier) obj;
+
+        return type == lhs.type
+                && role == lhs.role
+                && clientId == lhs.clientId
+                && sessionId == lhs.sessionId
+                && peerId == lhs.peerId
+                && Arrays.equals(peerMac, lhs.peerMac)
+                && Arrays.equals(pmk, lhs.pmk)
+                && Objects.equals(passphrase, lhs.passphrase);
+    }
+
+    /** @hide */
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("WifiAwareNetworkSpecifier [");
+        sb.append("type=").append(type)
+                .append(", role=").append(role)
+                .append(", clientId=").append(clientId)
+                .append(", sessionId=").append(sessionId)
+                .append(", peerId=").append(peerId)
+                // masking potential PII (although low impact information)
+                .append(", peerMac=").append((peerMac == null) ? "<null>" : "<non-null>")
+                // masking PII
+                .append(", pmk=").append((pmk == null) ? "<null>" : "<non-null>")
+                // masking PII
+                .append(", passphrase=").append((passphrase == null) ? "<null>" : "<non-null>")
+                .append("]");
+        return sb.toString();
+    }
+}
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareSession.java b/wifi/java/android/net/wifi/aware/WifiAwareSession.java
index 895defb..ac3a6bb 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareSession.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareSession.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.net.NetworkSpecifier;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.Looper;
@@ -184,8 +185,8 @@
     }
 
     /**
-     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} for an
-     * unencrypted WiFi Aware connection (link) to the specified peer. The
+     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} for
+     * an unencrypted WiFi Aware connection (link) to the specified peer. The
      * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
      * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
      * <p>
@@ -205,29 +206,29 @@
      *              peer. A RESPONDER may specify a {@code null} - indicating that it will accept
      *              connection requests from any device.
      *
-     * @return A string to be used to construct
-     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
+     * @return A {@link NetworkSpecifier} to be used to construct
+     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass to
      * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
      * android.net.ConnectivityManager.NetworkCallback)}
      * [or other varieties of that API].
      */
-    public String createNetworkSpecifierOpen(@WifiAwareManager.DataPathRole int role,
-            @Nullable byte[] peer) {
+    public NetworkSpecifier createNetworkSpecifierOpen(
+            @WifiAwareManager.DataPathRole int role, @Nullable byte[] peer) {
         WifiAwareManager mgr = mMgr.get();
         if (mgr == null) {
             Log.e(TAG, "createNetworkSpecifierOpen: called post GC on WifiAwareManager");
-            return "";
+            return null;
         }
         if (mTerminated) {
             Log.e(TAG, "createNetworkSpecifierOpen: called after termination");
-            return "";
+            return null;
         }
         return mgr.createNetworkSpecifier(mClientId, role, peer, null, null);
     }
 
     /**
-     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} for an
-     * encrypted WiFi Aware connection (link) to the specified peer. The
+     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} for
+     * an encrypted WiFi Aware connection (link) to the specified peer. The
      * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
      * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
      * <p>
@@ -247,22 +248,23 @@
      *                   the passphrase. Use {@link #createNetworkSpecifierOpen(int, byte[])} to
      *                   specify an open (unencrypted) link.
      *
-     * @return A string to be used to construct
-     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
+     * @return A {@link NetworkSpecifier} to be used to construct
+     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass to
      * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
      * android.net.ConnectivityManager.NetworkCallback)}
      * [or other varieties of that API].
      */
-    public String createNetworkSpecifierPassphrase(@WifiAwareManager.DataPathRole int role,
-            @Nullable byte[] peer, @NonNull String passphrase) {
+    public NetworkSpecifier createNetworkSpecifierPassphrase(
+            @WifiAwareManager.DataPathRole int role, @Nullable byte[] peer,
+            @NonNull String passphrase) {
         WifiAwareManager mgr = mMgr.get();
         if (mgr == null) {
             Log.e(TAG, "createNetworkSpecifierPassphrase: called post GC on WifiAwareManager");
-            return "";
+            return null;
         }
         if (mTerminated) {
             Log.e(TAG, "createNetworkSpecifierPassphrase: called after termination");
-            return "";
+            return null;
         }
         if (passphrase == null || passphrase.length() == 0) {
             throw new IllegalArgumentException("Passphrase must not be null or empty");
@@ -271,8 +273,8 @@
     }
 
     /**
-     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} for an
-     * encrypted WiFi Aware connection (link) to the specified peer. The
+     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} for
+     * an encrypted WiFi Aware connection (link) to the specified peer. The
      * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
      * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
      * <p>
@@ -294,8 +296,8 @@
      *            Passphrase or {@link #createNetworkSpecifierOpen(int, byte[])} to specify an
      *            open (unencrypted) link.
      *
-     * @return A string to be used to construct
-     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
+     * @return A {@link NetworkSpecifier} to be used to construct
+     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass to
      * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
      * android.net.ConnectivityManager.NetworkCallback)}
      * [or other varieties of that API].
@@ -303,16 +305,16 @@
      * @hide
      */
     @SystemApi
-    public String createNetworkSpecifierPmk(@WifiAwareManager.DataPathRole int role,
-            @Nullable byte[] peer, @NonNull byte[] pmk) {
+    public NetworkSpecifier createNetworkSpecifierPmk(
+            @WifiAwareManager.DataPathRole int role, @Nullable byte[] peer, @NonNull byte[] pmk) {
         WifiAwareManager mgr = mMgr.get();
         if (mgr == null) {
             Log.e(TAG, "createNetworkSpecifierPmk: called post GC on WifiAwareManager");
-            return "";
+            return null;
         }
         if (mTerminated) {
             Log.e(TAG, "createNetworkSpecifierPmk: called after termination");
-            return "";
+            return null;
         }
         if (pmk == null || pmk.length == 0) {
             throw new IllegalArgumentException("PMK must not be null or empty");
diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
index 830db22..72a6a7a 100644
--- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
@@ -34,11 +34,9 @@
 import android.os.Parcel;
 import android.os.test.TestLooper;
 import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Base64;
 
 import libcore.util.HexEncoding;
 
-import org.json.JSONObject;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -959,8 +957,6 @@
         final ConfigRequest configRequest = new ConfigRequest.Builder().build();
         final PublishConfig publishConfig = new PublishConfig.Builder().build();
 
-        String pmkB64 = Base64.encodeToString(pmk, Base64.DEFAULT);
-
         ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
                 WifiAwareSession.class);
         ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
@@ -991,51 +987,37 @@
         inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
 
         // (3) request an open (unencrypted) network specifier from the session
-        String networkSpecifier = publishSession.getValue().createNetworkSpecifierOpen(peerHandle);
+        WifiAwareNetworkSpecifier ns =
+                (WifiAwareNetworkSpecifier) publishSession.getValue().createNetworkSpecifierOpen(
+                        peerHandle);
 
         // validate format
-        JSONObject jsonObject = new JSONObject(networkSpecifier);
-        collector.checkThat("role", role,
-                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_ROLE)));
-        collector.checkThat("client_id", clientId,
-                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_CLIENT_ID)));
-        collector.checkThat("session_id", sessionId,
-                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_SESSION_ID)));
-        collector.checkThat("peer_id", peerHandle.peerId,
-                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_PEER_ID)));
+        collector.checkThat("role", role, equalTo(ns.role));
+        collector.checkThat("client_id", clientId, equalTo(ns.clientId));
+        collector.checkThat("session_id", sessionId, equalTo(ns.sessionId));
+        collector.checkThat("peer_id", peerHandle.peerId, equalTo(ns.peerId));
 
         // (4) request an encrypted (PMK) network specifier from the session
-        networkSpecifier = publishSession.getValue().createNetworkSpecifierPmk(peerHandle, pmk);
+        ns = (WifiAwareNetworkSpecifier) publishSession.getValue().createNetworkSpecifierPmk(
+                peerHandle, pmk);
 
         // validate format
-        jsonObject = new JSONObject(networkSpecifier);
-        collector.checkThat("role", role,
-                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_ROLE)));
-        collector.checkThat("client_id", clientId,
-                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_CLIENT_ID)));
-        collector.checkThat("session_id", sessionId,
-                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_SESSION_ID)));
-        collector.checkThat("peer_id", peerHandle.peerId,
-                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_PEER_ID)));
-        collector.checkThat("pmk", pmkB64 ,
-                equalTo(jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PMK)));
+        collector.checkThat("role", role, equalTo(ns.role));
+        collector.checkThat("client_id", clientId, equalTo(ns.clientId));
+        collector.checkThat("session_id", sessionId, equalTo(ns.sessionId));
+        collector.checkThat("peer_id", peerHandle.peerId, equalTo(ns.peerId));
+        collector.checkThat("pmk", pmk , equalTo(ns.pmk));
 
         // (5) request an encrypted (Passphrase) network specifier from the session
-        networkSpecifier = publishSession.getValue().createNetworkSpecifierPassphrase(peerHandle,
-                passphrase);
+        ns = (WifiAwareNetworkSpecifier) publishSession.getValue().createNetworkSpecifierPassphrase(
+                peerHandle, passphrase);
 
         // validate format
-        jsonObject = new JSONObject(networkSpecifier);
-        collector.checkThat("role", role,
-                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_ROLE)));
-        collector.checkThat("client_id", clientId,
-                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_CLIENT_ID)));
-        collector.checkThat("session_id", sessionId,
-                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_SESSION_ID)));
-        collector.checkThat("peer_id", peerHandle.peerId,
-                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_PEER_ID)));
-        collector.checkThat("passphrase", passphrase,
-                equalTo(jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PASSPHRASE)));
+        collector.checkThat("role", role, equalTo(ns.role));
+        collector.checkThat("client_id", clientId, equalTo(ns.clientId));
+        collector.checkThat("session_id", sessionId, equalTo(ns.sessionId));
+        collector.checkThat("peer_id", peerHandle.peerId, equalTo(ns.peerId));
+        collector.checkThat("passphrase", passphrase, equalTo(ns.passphrase));
 
         verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
                 mockPublishSession, mockRttListener);
@@ -1054,8 +1036,6 @@
         final byte[] pmk = "Some arbitrary pmk data".getBytes();
         final String passphrase = "A really bad password";
 
-        String pmkB64 = Base64.encodeToString(pmk, Base64.DEFAULT);
-
         ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
                 WifiAwareSession.class);
         ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor
@@ -1074,47 +1054,32 @@
         WifiAwareSession session = sessionCaptor.getValue();
 
         // (2) request an open (unencrypted) direct network specifier
-        String networkSpecifier = session.createNetworkSpecifierOpen(role, someMac);
+        WifiAwareNetworkSpecifier ns =
+                (WifiAwareNetworkSpecifier) session.createNetworkSpecifierOpen(role, someMac);
 
         // validate format
-        JSONObject jsonObject = new JSONObject(networkSpecifier);
-        collector.checkThat("role", role,
-                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_ROLE)));
-        collector.checkThat("client_id", clientId,
-                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_CLIENT_ID)));
-        collector.checkThat("peer_mac", someMac, equalTo(HexEncoding.decode(
-                jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PEER_MAC).toCharArray(),
-                false)));
+        collector.checkThat("role", role, equalTo(ns.role));
+        collector.checkThat("client_id", clientId, equalTo(ns.clientId));
+        collector.checkThat("peer_mac", someMac, equalTo(ns.peerMac));
 
         // (3) request an encrypted (PMK) direct network specifier
-        networkSpecifier = session.createNetworkSpecifierPmk(role, someMac, pmk);
+        ns = (WifiAwareNetworkSpecifier) session.createNetworkSpecifierPmk(role, someMac, pmk);
 
         // validate format
-        jsonObject = new JSONObject(networkSpecifier);
-        collector.checkThat("role", role,
-                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_ROLE)));
-        collector.checkThat("client_id", clientId,
-                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_CLIENT_ID)));
-        collector.checkThat("peer_mac", someMac, equalTo(HexEncoding.decode(
-                jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PEER_MAC).toCharArray(),
-                false)));
-        collector.checkThat("pmk", pmkB64,
-                equalTo(jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PMK)));
+        collector.checkThat("role", role, equalTo(ns.role));
+        collector.checkThat("client_id", clientId, equalTo(ns.clientId));
+        collector.checkThat("peer_mac", someMac, equalTo(ns.peerMac));
+        collector.checkThat("pmk", pmk, equalTo(ns.pmk));
 
         // (4) request an encrypted (Passphrase) direct network specifier
-        networkSpecifier = session.createNetworkSpecifierPassphrase(role, someMac, passphrase);
+        ns = (WifiAwareNetworkSpecifier) session.createNetworkSpecifierPassphrase(role, someMac,
+                passphrase);
 
         // validate format
-        jsonObject = new JSONObject(networkSpecifier);
-        collector.checkThat("role", role,
-                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_ROLE)));
-        collector.checkThat("client_id", clientId,
-                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_CLIENT_ID)));
-        collector.checkThat("peer_mac", someMac, equalTo(HexEncoding.decode(
-                jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PEER_MAC).toCharArray(),
-                false)));
-        collector.checkThat("passphrase", passphrase,
-                equalTo(jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PASSPHRASE)));
+        collector.checkThat("role", role, equalTo(ns.role));
+        collector.checkThat("client_id", clientId, equalTo(ns.clientId));
+        collector.checkThat("peer_mac", someMac, equalTo(ns.peerMac));
+        collector.checkThat("passphrase", passphrase, equalTo(ns.passphrase));
 
         verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
                 mockPublishSession, mockRttListener);