Merge "Add Java API for secure RTT protocol." into mm-wireless-dev
diff --git a/Android.mk b/Android.mk
index 7164778..7cb5fd3 100644
--- a/Android.mk
+++ b/Android.mk
@@ -410,9 +410,9 @@
 	telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
 	telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
 	wifi/java/android/net/wifi/IWifiManager.aidl \
-	wifi/java/android/net/wifi/nan/IWifiNanEventListener.aidl \
+	wifi/java/android/net/wifi/nan/IWifiNanEventCallback.aidl \
 	wifi/java/android/net/wifi/nan/IWifiNanManager.aidl \
-	wifi/java/android/net/wifi/nan/IWifiNanSessionListener.aidl \
+	wifi/java/android/net/wifi/nan/IWifiNanSessionCallback.aidl \
 	wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl \
 	wifi/java/android/net/wifi/IWifiScanner.aidl \
 	wifi/java/android/net/wifi/IRttManager.aidl \
@@ -480,10 +480,8 @@
 	frameworks/base/media/java/android/media/browse/MediaBrowser.aidl \
 	frameworks/base/wifi/java/android/net/wifi/ScanSettings.aidl \
 	frameworks/base/wifi/java/android/net/wifi/nan/ConfigRequest.aidl \
-	frameworks/base/wifi/java/android/net/wifi/nan/PublishData.aidl \
-	frameworks/base/wifi/java/android/net/wifi/nan/SubscribeData.aidl \
-	frameworks/base/wifi/java/android/net/wifi/nan/PublishSettings.aidl \
-	frameworks/base/wifi/java/android/net/wifi/nan/SubscribeSettings.aidl \
+	frameworks/base/wifi/java/android/net/wifi/nan/PublishConfig.aidl \
+	frameworks/base/wifi/java/android/net/wifi/nan/SubscribeConfig.aidl \
 	frameworks/base/wifi/java/android/net/wifi/p2p/WifiP2pInfo.aidl \
 	frameworks/base/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.aidl \
 	frameworks/base/wifi/java/android/net/wifi/p2p/WifiP2pConfig.aidl \
diff --git a/api/system-current.txt b/api/system-current.txt
index f88ddaf..3706140 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -21218,7 +21218,6 @@
     field public static final int REASON_UNSPECIFIED = -1; // 0xffffffff
     field public static final deprecated int REPORT_EVENT_AFTER_BUFFER_FULL = 0; // 0x0
     field public static final int REPORT_EVENT_AFTER_EACH_SCAN = 1; // 0x1
-    field public static final int REPORT_EVENT_CONTEXT_HUB = 8; // 0x8
     field public static final int REPORT_EVENT_FULL_SCAN_RESULT = 2; // 0x2
     field public static final int REPORT_EVENT_NO_BATCH = 4; // 0x4
     field public static final int WIFI_BAND_24_GHZ = 1; // 0x1
diff --git a/core/java/android/net/BaseDhcpStateMachine.java b/core/java/android/net/BaseDhcpStateMachine.java
deleted file mode 100644
index a25847d..0000000
--- a/core/java/android/net/BaseDhcpStateMachine.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2015 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;
-
-import com.android.internal.util.StateMachine;
-
-/**
- * Interface that must be implemented by DHCP state machines.
- *
- * This is an abstract class instead of a Java interface so that callers can just declare an object
- * of this type and be able to call all the methods defined by either StateMachine or this class.
- *
- * @hide
- */
-public abstract class BaseDhcpStateMachine extends StateMachine {
-    protected BaseDhcpStateMachine(String tag) {
-        super(tag);
-    }
-    public abstract void registerForPreDhcpNotification();
-    public abstract void doQuit();
-}
diff --git a/core/java/android/net/DhcpStateMachine.java b/core/java/android/net/DhcpStateMachine.java
deleted file mode 100644
index 73ef78e..0000000
--- a/core/java/android/net/DhcpStateMachine.java
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import com.android.internal.util.Protocol;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.DhcpResults;
-import android.net.NetworkUtils;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.SystemClock;
-import android.util.Log;
-
-/**
- * StateMachine that interacts with the native DHCP client and can talk to
- * a controller that also needs to be a StateMachine
- *
- * The DhcpStateMachine provides the following features:
- * - Wakeup and renewal using the native DHCP client  (which will not renew
- *   on its own when the device is in suspend state and this can lead to device
- *   holding IP address beyond expiry)
- * - A notification right before DHCP request or renewal is started. This
- *   can be used for any additional setup before DHCP. For example, wifi sets
- *   BT-Wifi coex settings right before DHCP is initiated
- *
- * @hide
- */
-public class DhcpStateMachine extends BaseDhcpStateMachine {
-
-    private static final String TAG = "DhcpStateMachine";
-    private static final boolean DBG = false;
-
-
-    /* A StateMachine that controls the DhcpStateMachine */
-    private StateMachine mController;
-
-    private Context mContext;
-    private BroadcastReceiver mBroadcastReceiver;
-    private AlarmManager mAlarmManager;
-    private PendingIntent mDhcpRenewalIntent;
-    private PowerManager.WakeLock mDhcpRenewWakeLock;
-    private static final String WAKELOCK_TAG = "DHCP";
-
-    //Remember DHCP configuration from first request
-    private DhcpResults mDhcpResults;
-
-    private static final int DHCP_RENEW = 0;
-    private static final String ACTION_DHCP_RENEW = "android.net.wifi.DHCP_RENEW";
-
-    //Used for sanity check on setting up renewal
-    private static final int MIN_RENEWAL_TIME_SECS = 5 * 60;  // 5 minutes
-
-    private final String mInterfaceName;
-    private boolean mRegisteredForPreDhcpNotification = false;
-
-    private static final int BASE = Protocol.BASE_DHCP;
-
-    /* Commands from controller to start/stop DHCP */
-    public static final int CMD_START_DHCP                  = BASE + 1;
-    public static final int CMD_STOP_DHCP                   = BASE + 2;
-    public static final int CMD_RENEW_DHCP                  = BASE + 3;
-
-    /* Notification from DHCP state machine prior to DHCP discovery/renewal */
-    public static final int CMD_PRE_DHCP_ACTION             = BASE + 4;
-    /* Notification from DHCP state machine post DHCP discovery/renewal. Indicates
-     * success/failure */
-    public static final int CMD_POST_DHCP_ACTION            = BASE + 5;
-    /* Notification from DHCP state machine before quitting */
-    public static final int CMD_ON_QUIT                     = BASE + 6;
-
-    /* Command from controller to indicate DHCP discovery/renewal can continue
-     * after pre DHCP action is complete */
-    public static final int CMD_PRE_DHCP_ACTION_COMPLETE    = BASE + 7;
-
-    /* Command from ourselves to see if DHCP results are available */
-    private static final int CMD_GET_DHCP_RESULTS           = BASE + 8;
-
-    /* Message.arg1 arguments to CMD_POST_DHCP notification */
-    public static final int DHCP_SUCCESS = 1;
-    public static final int DHCP_FAILURE = 2;
-
-    private State mDefaultState = new DefaultState();
-    private State mStoppedState = new StoppedState();
-    private State mWaitBeforeStartState = new WaitBeforeStartState();
-    private State mRunningState = new RunningState();
-    private State mWaitBeforeRenewalState = new WaitBeforeRenewalState();
-    private State mPollingState = new PollingState();
-
-    private DhcpStateMachine(Context context, StateMachine controller, String intf) {
-        super(TAG);
-
-        mContext = context;
-        mController = controller;
-        mInterfaceName = intf;
-
-        mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
-        Intent dhcpRenewalIntent = new Intent(ACTION_DHCP_RENEW, null);
-        mDhcpRenewalIntent = PendingIntent.getBroadcast(mContext, DHCP_RENEW, dhcpRenewalIntent, 0);
-
-        PowerManager powerManager = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
-        mDhcpRenewWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG);
-        mDhcpRenewWakeLock.setReferenceCounted(false);
-
-        mBroadcastReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                //DHCP renew
-                if (DBG) Log.d(TAG, "Sending a DHCP renewal " + this);
-                //Lock released after 40s in worst case scenario
-                mDhcpRenewWakeLock.acquire(40000);
-                sendMessage(CMD_RENEW_DHCP);
-            }
-        };
-        mContext.registerReceiver(mBroadcastReceiver, new IntentFilter(ACTION_DHCP_RENEW));
-
-        addState(mDefaultState);
-            addState(mStoppedState, mDefaultState);
-            addState(mWaitBeforeStartState, mDefaultState);
-            addState(mPollingState, mDefaultState);
-            addState(mRunningState, mDefaultState);
-            addState(mWaitBeforeRenewalState, mDefaultState);
-
-        setInitialState(mStoppedState);
-    }
-
-    public static DhcpStateMachine makeDhcpStateMachine(Context context, StateMachine controller,
-            String intf) {
-        DhcpStateMachine dsm = new DhcpStateMachine(context, controller, intf);
-        dsm.start();
-        return dsm;
-    }
-
-    /**
-     * This sends a notification right before DHCP request/renewal so that the
-     * controller can do certain actions before DHCP packets are sent out.
-     * When the controller is ready, it sends a CMD_PRE_DHCP_ACTION_COMPLETE message
-     * to indicate DHCP can continue
-     *
-     * This is used by Wifi at this time for the purpose of doing BT-Wifi coex
-     * handling during Dhcp
-     */
-    @Override
-    public void registerForPreDhcpNotification() {
-        mRegisteredForPreDhcpNotification = true;
-    }
-
-    /**
-     * Quit the DhcpStateMachine.
-     *
-     * @hide
-     */
-    @Override
-    public void doQuit() {
-        quit();
-    }
-
-    protected void onQuitting() {
-        mController.sendMessage(CMD_ON_QUIT);
-    }
-
-    class DefaultState extends State {
-        @Override
-        public void exit() {
-            mContext.unregisterReceiver(mBroadcastReceiver);
-        }
-        @Override
-        public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
-            switch (message.what) {
-                case CMD_RENEW_DHCP:
-                    Log.e(TAG, "Error! Failed to handle a DHCP renewal on " + mInterfaceName);
-                    mDhcpRenewWakeLock.release();
-                    break;
-                default:
-                    Log.e(TAG, "Error! unhandled message  " + message);
-                    break;
-            }
-            return HANDLED;
-        }
-    }
-
-
-    class StoppedState extends State {
-        @Override
-        public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
-            if (!NetworkUtils.stopDhcp(mInterfaceName)) {
-                Log.e(TAG, "Failed to stop Dhcp on " + mInterfaceName);
-            }
-            mDhcpResults = null;
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            boolean retValue = HANDLED;
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
-            switch (message.what) {
-                case CMD_START_DHCP:
-                    if (mRegisteredForPreDhcpNotification) {
-                        /* Notify controller before starting DHCP */
-                        mController.sendMessage(CMD_PRE_DHCP_ACTION);
-                        transitionTo(mWaitBeforeStartState);
-                    } else {
-                        if (runDhcpStart()) {
-                            transitionTo(mRunningState);
-                        }
-                    }
-                    break;
-                case CMD_STOP_DHCP:
-                    //ignore
-                    break;
-                default:
-                    retValue = NOT_HANDLED;
-                    break;
-            }
-            return retValue;
-        }
-    }
-
-    class WaitBeforeStartState extends State {
-        @Override
-        public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            boolean retValue = HANDLED;
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
-            switch (message.what) {
-                case CMD_PRE_DHCP_ACTION_COMPLETE:
-                    if (runDhcpStart()) {
-                        transitionTo(mRunningState);
-                    } else {
-                        transitionTo(mPollingState);
-                    }
-                    break;
-                case CMD_STOP_DHCP:
-                    transitionTo(mStoppedState);
-                    break;
-                case CMD_START_DHCP:
-                    //ignore
-                    break;
-                default:
-                    retValue = NOT_HANDLED;
-                    break;
-            }
-            return retValue;
-        }
-    }
-
-    class PollingState extends State {
-        private static final long MAX_DELAY_SECONDS = 32;
-        private long delaySeconds;
-
-        private void scheduleNextResultsCheck() {
-            sendMessageDelayed(obtainMessage(CMD_GET_DHCP_RESULTS), delaySeconds * 1000);
-            delaySeconds *= 2;
-            if (delaySeconds > MAX_DELAY_SECONDS) {
-                delaySeconds = MAX_DELAY_SECONDS;
-            }
-        }
-
-        @Override
-        public void enter() {
-            if (DBG) Log.d(TAG, "Entering " + getName() + "\n");
-            delaySeconds = 1;
-            scheduleNextResultsCheck();
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            boolean retValue = HANDLED;
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
-            switch (message.what) {
-                case CMD_GET_DHCP_RESULTS:
-                    if (DBG) Log.d(TAG, "GET_DHCP_RESULTS on " + mInterfaceName);
-                    if (dhcpSucceeded()) {
-                        transitionTo(mRunningState);
-                    } else {
-                        scheduleNextResultsCheck();
-                    }
-                    break;
-                case CMD_STOP_DHCP:
-                    transitionTo(mStoppedState);
-                    break;
-                default:
-                    retValue = NOT_HANDLED;
-                    break;
-            }
-            return retValue;
-        }
-
-        @Override
-        public void exit() {
-            if (DBG) Log.d(TAG, "Exiting " + getName() + "\n");
-            removeMessages(CMD_GET_DHCP_RESULTS);
-        }
-    }
-
-    class RunningState extends State {
-        @Override
-        public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            boolean retValue = HANDLED;
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
-            switch (message.what) {
-                case CMD_STOP_DHCP:
-                    mAlarmManager.cancel(mDhcpRenewalIntent);
-                    transitionTo(mStoppedState);
-                    break;
-                case CMD_RENEW_DHCP:
-                    if (mRegisteredForPreDhcpNotification) {
-                        /* Notify controller before starting DHCP */
-                        mController.sendMessage(CMD_PRE_DHCP_ACTION);
-                        transitionTo(mWaitBeforeRenewalState);
-                        //mDhcpRenewWakeLock is released in WaitBeforeRenewalState
-                    } else {
-                        if (!runDhcpRenew()) {
-                            transitionTo(mStoppedState);
-                        }
-                        mDhcpRenewWakeLock.release();
-                    }
-                    break;
-                case CMD_START_DHCP:
-                    //ignore
-                    break;
-                default:
-                    retValue = NOT_HANDLED;
-            }
-            return retValue;
-        }
-    }
-
-    class WaitBeforeRenewalState extends State {
-        @Override
-        public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            boolean retValue = HANDLED;
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
-            switch (message.what) {
-                case CMD_STOP_DHCP:
-                    mAlarmManager.cancel(mDhcpRenewalIntent);
-                    transitionTo(mStoppedState);
-                    break;
-                case CMD_PRE_DHCP_ACTION_COMPLETE:
-                    if (runDhcpRenew()) {
-                       transitionTo(mRunningState);
-                    } else {
-                       transitionTo(mStoppedState);
-                    }
-                    break;
-                case CMD_START_DHCP:
-                    //ignore
-                    break;
-                default:
-                    retValue = NOT_HANDLED;
-                    break;
-            }
-            return retValue;
-        }
-        @Override
-        public void exit() {
-            mDhcpRenewWakeLock.release();
-        }
-    }
-
-    private boolean dhcpSucceeded() {
-        DhcpResults dhcpResults = new DhcpResults();
-        if (!NetworkUtils.getDhcpResults(mInterfaceName, dhcpResults)) {
-            return false;
-        }
-
-        if (DBG) Log.d(TAG, "DHCP results found for " + mInterfaceName);
-        long leaseDuration = dhcpResults.leaseDuration; //int to long conversion
-
-        //Sanity check for renewal
-        if (leaseDuration >= 0) {
-            //TODO: would be good to notify the user that his network configuration is
-            //bad and that the device cannot renew below MIN_RENEWAL_TIME_SECS
-            if (leaseDuration < MIN_RENEWAL_TIME_SECS) {
-                leaseDuration = MIN_RENEWAL_TIME_SECS;
-            }
-            //Do it a bit earlier than half the lease duration time
-            //to beat the native DHCP client and avoid extra packets
-            //48% for one hour lease time = 29 minutes
-            mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                    SystemClock.elapsedRealtime() +
-                    leaseDuration * 480, //in milliseconds
-                    mDhcpRenewalIntent);
-        } else {
-            //infinite lease time, no renewal needed
-        }
-
-        // Fill in any missing fields in dhcpResults from the previous results.
-        // If mDhcpResults is null (i.e. this is the first server response),
-        // this is a noop.
-        dhcpResults.updateFromDhcpRequest(mDhcpResults);
-        mDhcpResults = dhcpResults;
-        mController.obtainMessage(CMD_POST_DHCP_ACTION, DHCP_SUCCESS, 0, dhcpResults)
-            .sendToTarget();
-        return true;
-    }
-
-    private boolean runDhcpStart() {
-        /* Stop any existing DHCP daemon before starting new */
-        NetworkUtils.stopDhcp(mInterfaceName);
-        mDhcpResults = null;
-
-        if (DBG) Log.d(TAG, "DHCP request on " + mInterfaceName);
-        if (!NetworkUtils.startDhcp(mInterfaceName) || !dhcpSucceeded()) {
-            Log.e(TAG, "DHCP request failed on " + mInterfaceName + ": " +
-                    NetworkUtils.getDhcpError());
-            mController.obtainMessage(CMD_POST_DHCP_ACTION, DHCP_FAILURE, 0)
-                    .sendToTarget();
-            return false;
-        }
-        return true;
-    }
-
-    private boolean runDhcpRenew() {
-        if (DBG) Log.d(TAG, "DHCP renewal on " + mInterfaceName);
-        if (!NetworkUtils.startDhcpRenew(mInterfaceName) || !dhcpSucceeded()) {
-            Log.e(TAG, "DHCP renew failed on " + mInterfaceName + ": " +
-                    NetworkUtils.getDhcpError());
-            mController.obtainMessage(CMD_POST_DHCP_ACTION, DHCP_FAILURE, 0)
-                    .sendToTarget();
-            return false;
-        }
-        return true;
-    }
-}
diff --git a/core/java/com/android/internal/util/MessageUtils.java b/core/java/com/android/internal/util/MessageUtils.java
new file mode 100644
index 0000000..1014bfd
--- /dev/null
+++ b/core/java/com/android/internal/util/MessageUtils.java
@@ -0,0 +1,127 @@
+/*
+ * 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.internal.util;
+
+import android.os.Message;
+import android.util.Log;
+import android.util.SparseArray;
+
+import java.lang.reflect.Field;
+
+/**
+ * Static utility class for dealing with {@link Message} objects.
+ */
+public class MessageUtils {
+
+    private static final String TAG = MessageUtils.class.getSimpleName();
+    private static final boolean DBG = false;
+
+    /** Thrown when two different constants have the same value. */
+    public static class DuplicateConstantError extends Error {
+        private DuplicateConstantError() {}
+        public DuplicateConstantError(String name1, String name2, int value) {
+            super(String.format("Duplicate constant value: both %s and %s = %d",
+                name1, name2, value));
+        }
+    }
+
+    /**
+     * Finds the names of integer constants. Searches the specified {@code classes}, looking for
+     * accessible static integer fields whose names begin with one of the specified {@prefixes}.
+     *
+     * @param classes the classes to examine.
+     * @prefixes only consider fields names starting with one of these prefixes.
+     * @return a {@link SparseArray} mapping integer constants to their names.
+     */
+    public static SparseArray<String> findMessageNames(Class[] classes, String[] prefixes) {
+        SparseArray<String> messageNames = new SparseArray<>();
+        for (Class c : classes) {
+            String className = c.getName();
+            if (DBG) Log.d(TAG, "Examining class " + className);
+
+            Field[] fields;
+            try {
+                fields = c.getDeclaredFields();
+            } catch (SecurityException e) {
+                Log.e(TAG, "Can't list fields of class " + className);
+                continue;
+            }
+
+            for (Field field : fields) {
+                String name = field.getName();
+
+                for (String prefix : prefixes) {
+                    // Does this look like a constant?
+                    if (!name.startsWith(prefix)) {
+                        continue;
+                    }
+
+                    try {
+                        // TODO: can we have the caller try to access the field instead, so we don't
+                        // expose constants it does not have access to?
+                        field.setAccessible(true);
+
+                        // Fetch the constant's value.
+                        int value;
+                        try {
+                            value = field.getInt(null);
+                        } catch (IllegalArgumentException | ExceptionInInitializerError e) {
+                            // The field is not an integer (or short or byte), or c's static
+                            // initializer failed and we have no idea what its value is.
+                            // Either way, give up on this field.
+                            break;
+                        }
+
+                        // Check for duplicate values.
+                        String previousName = messageNames.get(value);
+                        if (previousName != null && !previousName.equals(name)) {
+                            throw new DuplicateConstantError(name, previousName, value);
+                        }
+
+                        messageNames.put(value, name);
+                        if (DBG) {
+                            Log.d(TAG, String.format("Found constant: %s.%s = %d",
+                                    className, name, value));
+                        }
+                    } catch (SecurityException | IllegalAccessException e) {
+                        // Not allowed to make the field accessible, or no access. Ignore.
+                        continue;
+                    }
+                }
+            }
+        }
+        return messageNames;
+    }
+
+    /**
+     * Default prefixes for constants.
+     */
+    public static final String[] DEFAULT_PREFIXES = {"CMD_", "EVENT_"};
+
+    /**
+     * Finds the names of integer constants. Searches the specified {@code classes}, looking for
+     * accessible static integer values whose names begin with {@link #DEFAULT_PREFIXES}.
+     *
+     * @param classNames the classes to examine.
+     * @prefixes only consider fields names starting with one of these prefixes.
+     * @return a {@link SparseArray} mapping integer constants to their names.
+     */
+    public static SparseArray<String> findMessageNames(Class[] classNames) {
+        return findMessageNames(classNames, DEFAULT_PREFIXES);
+    }
+}
+
diff --git a/core/java/com/android/internal/util/Protocol.java b/core/java/com/android/internal/util/Protocol.java
index a106f48..5992f7a 100644
--- a/core/java/com/android/internal/util/Protocol.java
+++ b/core/java/com/android/internal/util/Protocol.java
@@ -64,5 +64,6 @@
     public static final int BASE_NETWORK_AGENT                                      = 0x00081000;
     public static final int BASE_NETWORK_MONITOR                                    = 0x00082000;
     public static final int BASE_NETWORK_FACTORY                                    = 0x00083000;
+    public static final int BASE_ETHERNET                                           = 0x00084000;
     //TODO: define all used protocols
 }
diff --git a/core/java/com/android/internal/util/WakeupMessage.java b/core/java/com/android/internal/util/WakeupMessage.java
new file mode 100644
index 0000000..77859b8
--- /dev/null
+++ b/core/java/com/android/internal/util/WakeupMessage.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2015 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.internal.util;
+
+import android.app.AlarmManager;
+import android.content.Context;
+import android.os.Handler;
+import android.os.Message;
+
+ /**
+ * An AlarmListener that sends the specified message to a Handler and keeps the system awake until
+ * the message is processed.
+ *
+ * This is useful when using the AlarmManager direct callback interface to wake up the system and
+ * request that an object whose API consists of messages (such as a StateMachine) perform some
+ * action.
+ *
+ * In this situation, using AlarmManager.onAlarmListener by itself will wake up the system to send
+ * the message, but does not guarantee that the system will be awake until the target object has
+ * processed it. This is because as soon as the onAlarmListener sends the message and returns, the
+ * AlarmManager releases its wakelock and the system is free to go to sleep again.
+ *
+ */
+public class WakeupMessage implements AlarmManager.OnAlarmListener {
+    private static AlarmManager sAlarmManager;
+    private final Handler mHandler;
+    private final String mCmdName;
+    private final int mCmd, mArg1, mArg2;
+
+    public WakeupMessage(Context context, Handler handler,
+            String cmdName, int cmd, int arg1, int arg2) {
+        if (sAlarmManager == null) {
+            sAlarmManager = context.getSystemService(AlarmManager.class);
+        }
+        mHandler = handler;
+        mCmdName = cmdName;
+        mCmd = cmd;
+        mArg1 = arg1;
+        mArg2 = arg2;
+    }
+
+    public WakeupMessage(Context context, Handler handler, String cmdName, int cmd, int arg1) {
+        this(context, handler, cmdName, cmd, arg1, 0);
+    }
+
+    public WakeupMessage(Context context, Handler handler, String cmdName, int cmd) {
+        this(context, handler, cmdName, cmd, 0, 0);
+    }
+
+    public void schedule(long when) {
+        sAlarmManager.setExact(
+                AlarmManager.ELAPSED_REALTIME_WAKEUP, when, mCmdName, this, mHandler);
+    }
+
+    public void cancel() {
+        sAlarmManager.cancel(this);
+    }
+
+    @Override
+    public void onAlarm() {
+        Message msg = mHandler.obtainMessage(mCmd, mArg1, mArg2);
+        mHandler.handleMessage(msg);
+        msg.recycle();
+    }
+}
diff --git a/core/tests/utiltests/Android.mk b/core/tests/utiltests/Android.mk
new file mode 100644
index 0000000..f949e1a
--- /dev/null
+++ b/core/tests/utiltests/Android.mk
@@ -0,0 +1,23 @@
+#########################################################################
+# Build FrameworksUtilTests package
+#########################################################################
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := tests
+
+# Include all test java files.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    android-support-test
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_PACKAGE_NAME := FrameworksUtilTests
+
+LOCAL_CERTIFICATE := platform
+
+include $(BUILD_PACKAGE)
diff --git a/core/tests/utiltests/AndroidManifest.xml b/core/tests/utiltests/AndroidManifest.xml
new file mode 100644
index 0000000..fecaf8e
--- /dev/null
+++ b/core/tests/utiltests/AndroidManifest.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.frameworks.utiltests">
+
+    <uses-permission android:name="android.permission.READ_LOGS" />
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
+    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+    <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
+    <uses-permission android:name="android.permission.MANAGE_APP_TOKENS" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+
+    <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
+    <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" />
+    <uses-permission android:name="android.permission.MODIFY_NETWORK_ACCOUNTING" />
+    <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.MANAGE_USERS" />
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+    <uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />
+    <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.frameworks.utiltests"
+        android:label="Frameworks Utility Tests" />
+
+</manifest>
diff --git a/core/tests/coretests/src/com/android/internal/util/ArrayUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java
similarity index 100%
rename from core/tests/coretests/src/com/android/internal/util/ArrayUtilsTest.java
rename to core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java
diff --git a/core/tests/coretests/src/com/android/internal/util/AsyncChannelTest.java b/core/tests/utiltests/src/com/android/internal/util/AsyncChannelTest.java
similarity index 100%
rename from core/tests/coretests/src/com/android/internal/util/AsyncChannelTest.java
rename to core/tests/utiltests/src/com/android/internal/util/AsyncChannelTest.java
diff --git a/core/tests/coretests/src/com/android/internal/util/BitwiseStreamsTest.java b/core/tests/utiltests/src/com/android/internal/util/BitwiseStreamsTest.java
similarity index 100%
rename from core/tests/coretests/src/com/android/internal/util/BitwiseStreamsTest.java
rename to core/tests/utiltests/src/com/android/internal/util/BitwiseStreamsTest.java
diff --git a/core/tests/coretests/src/com/android/internal/util/CallbackRegistryTest.java b/core/tests/utiltests/src/com/android/internal/util/CallbackRegistryTest.java
similarity index 100%
rename from core/tests/coretests/src/com/android/internal/util/CallbackRegistryTest.java
rename to core/tests/utiltests/src/com/android/internal/util/CallbackRegistryTest.java
diff --git a/core/tests/coretests/src/com/android/internal/util/CharSequencesTest.java b/core/tests/utiltests/src/com/android/internal/util/CharSequencesTest.java
similarity index 100%
rename from core/tests/coretests/src/com/android/internal/util/CharSequencesTest.java
rename to core/tests/utiltests/src/com/android/internal/util/CharSequencesTest.java
diff --git a/core/tests/coretests/src/com/android/internal/util/FastXmlSerializerTest.java b/core/tests/utiltests/src/com/android/internal/util/FastXmlSerializerTest.java
similarity index 100%
rename from core/tests/coretests/src/com/android/internal/util/FastXmlSerializerTest.java
rename to core/tests/utiltests/src/com/android/internal/util/FastXmlSerializerTest.java
diff --git a/core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java b/core/tests/utiltests/src/com/android/internal/util/FileRotatorTest.java
similarity index 100%
rename from core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java
rename to core/tests/utiltests/src/com/android/internal/util/FileRotatorTest.java
diff --git a/core/tests/coretests/src/com/android/internal/util/IndentingPrintWriterTest.java b/core/tests/utiltests/src/com/android/internal/util/IndentingPrintWriterTest.java
similarity index 100%
rename from core/tests/coretests/src/com/android/internal/util/IndentingPrintWriterTest.java
rename to core/tests/utiltests/src/com/android/internal/util/IndentingPrintWriterTest.java
diff --git a/core/tests/coretests/src/com/android/internal/util/PredicatesTest.java b/core/tests/utiltests/src/com/android/internal/util/PredicatesTest.java
similarity index 100%
rename from core/tests/coretests/src/com/android/internal/util/PredicatesTest.java
rename to core/tests/utiltests/src/com/android/internal/util/PredicatesTest.java
diff --git a/core/tests/coretests/src/com/android/internal/util/ProcFileReaderTest.java b/core/tests/utiltests/src/com/android/internal/util/ProcFileReaderTest.java
similarity index 100%
rename from core/tests/coretests/src/com/android/internal/util/ProcFileReaderTest.java
rename to core/tests/utiltests/src/com/android/internal/util/ProcFileReaderTest.java
diff --git a/core/tests/coretests/src/com/android/internal/util/StateMachineTest.java b/core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java
similarity index 100%
rename from core/tests/coretests/src/com/android/internal/util/StateMachineTest.java
rename to core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java
diff --git a/core/tests/coretests/src/com/android/internal/util/XmlUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/XmlUtilsTest.java
similarity index 100%
rename from core/tests/coretests/src/com/android/internal/util/XmlUtilsTest.java
rename to core/tests/utiltests/src/com/android/internal/util/XmlUtilsTest.java
diff --git a/services/net/java/android/net/dhcp/DhcpClient.java b/services/net/java/android/net/dhcp/DhcpClient.java
index f9c17b7..7fc6c5b 100644
--- a/services/net/java/android/net/dhcp/DhcpClient.java
+++ b/services/net/java/android/net/dhcp/DhcpClient.java
@@ -19,6 +19,7 @@
 import com.android.internal.util.HexDump;
 import com.android.internal.util.Protocol;
 import com.android.internal.util.State;
+import com.android.internal.util.MessageUtils;
 import com.android.internal.util.StateMachine;
 
 import android.app.AlarmManager;
@@ -28,14 +29,12 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.net.DhcpResults;
-import android.net.BaseDhcpStateMachine;
 import android.net.InterfaceConfiguration;
 import android.net.LinkAddress;
 import android.net.NetworkUtils;
 import android.os.IBinder;
 import android.os.INetworkManagementService;
 import android.os.Message;
-import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
@@ -43,16 +42,15 @@
 import android.system.Os;
 import android.system.PacketSocketAddress;
 import android.util.Log;
+import android.util.SparseArray;
 import android.util.TimeUtils;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.lang.Thread;
 import java.net.Inet4Address;
-import java.net.InetSocketAddress;
 import java.net.NetworkInterface;
 import java.net.SocketException;
-import java.nio.BufferUnderflowException;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
 import java.util.Random;
@@ -85,7 +83,7 @@
  *
  * @hide
  */
-public class DhcpClient extends BaseDhcpStateMachine {
+public class DhcpClient extends StateMachine {
 
     private static final String TAG = "DhcpClient";
     private static final boolean DBG = true;
@@ -134,6 +132,11 @@
     private static final int CMD_TIMEOUT          = PRIVATE_BASE + 3;
     private static final int CMD_ONESHOT_TIMEOUT  = PRIVATE_BASE + 4;
 
+    // For message logging.
+    private static final Class[] sMessageClasses = { DhcpClient.class };
+    private static final SparseArray<String> sMessageNames =
+            MessageUtils.findMessageNames(sMessageClasses);
+
     // DHCP parameters that we request.
     private static final byte[] REQUESTED_PARAMS = new byte[] {
         DHCP_SUBNET_MASK,
@@ -240,12 +243,11 @@
                 CMD_ONESHOT_TIMEOUT);
     }
 
-    @Override
     public void registerForPreDhcpNotification() {
         mRegisteredForPreDhcpNotification = true;
     }
 
-    public static BaseDhcpStateMachine makeDhcpStateMachine(
+    public static DhcpClient makeDhcpClient(
             Context context, StateMachine controller, String intf) {
         DhcpClient client = new DhcpClient(context, controller, intf);
         client.start();
@@ -478,12 +480,12 @@
      *
      * @hide
      */
-    @Override
     public void doQuit() {
         Log.d(TAG, "doQuit");
         quit();
     }
 
+    @Override
     protected void onQuitting() {
         Log.d(TAG, "onQuitting");
         mController.sendMessage(CMD_ON_QUIT);
@@ -499,30 +501,7 @@
         }
 
         private String messageName(int what) {
-            switch (what) {
-                case CMD_START_DHCP:
-                    return "CMD_START_DHCP";
-                case CMD_STOP_DHCP:
-                    return "CMD_STOP_DHCP";
-                case CMD_RENEW_DHCP:
-                    return "CMD_RENEW_DHCP";
-                case CMD_PRE_DHCP_ACTION:
-                    return "CMD_PRE_DHCP_ACTION";
-                case CMD_PRE_DHCP_ACTION_COMPLETE:
-                    return "CMD_PRE_DHCP_ACTION_COMPLETE";
-                case CMD_POST_DHCP_ACTION:
-                    return "CMD_POST_DHCP_ACTION";
-                case CMD_KICK:
-                    return "CMD_KICK";
-                case CMD_RECEIVED_PACKET:
-                    return "CMD_RECEIVED_PACKET";
-                case CMD_TIMEOUT:
-                    return "CMD_TIMEOUT";
-                case CMD_ONESHOT_TIMEOUT:
-                    return "CMD_ONESHOT_TIMEOUT";
-                default:
-                    return Integer.toString(what);
-            }
+            return sMessageNames.get(what, Integer.toString(what));
         }
 
         private String messageToString(Message message) {
@@ -866,7 +845,7 @@
             super.enter();
             cancelOneshotTimeout();
             notifySuccess();
-            // TODO: DhcpStateMachine only supports renewing at 50% of the lease time, and does not
+            // TODO: DhcpStateMachine only supported renewing at 50% of the lease time, and did not
             // support rebinding. Once the legacy DHCP client is gone, fix this.
             scheduleRenew();
         }
@@ -929,7 +908,7 @@
         }
     }
 
-    // Not implemented. DhcpStateMachine does not implement it either.
+    // Not implemented. DhcpStateMachine did not implement it either.
     class DhcpRebindingState extends LoggingState {
     }
 
diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java
index 25cb793..61f2c8a 100644
--- a/services/net/java/android/net/ip/IpManager.java
+++ b/services/net/java/android/net/ip/IpManager.java
@@ -16,10 +16,10 @@
 
 package android.net.ip;
 
+import com.android.internal.util.MessageUtils;
+
 import android.content.Context;
-import android.net.BaseDhcpStateMachine;
 import android.net.DhcpResults;
-import android.net.DhcpStateMachine;
 import android.net.InterfaceConfiguration;
 import android.net.LinkAddress;
 import android.net.LinkProperties;
@@ -31,8 +31,8 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.provider.Settings;
 import android.util.Log;
+import android.util.SparseArray;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -64,35 +64,21 @@
     private static final boolean DBG = true;
     private static final boolean VDBG = false;
 
+    // For message logging.
+    private static final Class[] sMessageClasses = { IpManager.class, DhcpClient.class };
+    private static final SparseArray<String> sWhatToString =
+            MessageUtils.findMessageNames(sMessageClasses);
+
     /**
-     * Callbacks for both configuration of IpManager and for handling
-     * events as desired.
+     * Callbacks for handling IpManager events.
      */
     public static class Callback {
-        /**
-         * Configuration callbacks.
-         *
-         * Override methods as desired in order to control which features
-         * IpManager will use at run time.
-         */
-
-        // An IpReachabilityMonitor will always be started, if only for logging.
-        // This method is checked before probing neighbors and before calling
-        // onProvisioningLost() (see below).
-        public boolean usingIpReachabilityMonitor() {
-            return false;
-        }
-
-        /**
-         * Event callbacks.
-         *
-         * Override methods as desired in order to handle event callbacks
-         * as IpManager invokes them.
-         */
-
-        // Implementations must call IpManager#completedPreDhcpAction().
-        // TODO: Remove this requirement, perhaps via some
-        // registerForPreDhcpAction()-style mechanism.
+        // In order to receive onPreDhcpAction(), call #withPreDhcpAction()
+        // when constructing a ProvisioningConfiguration.
+        //
+        // Implementations of onPreDhcpAction() must call
+        // IpManager#completedPreDhcpAction() to indicate that DHCP is clear
+        // to proceed.
         public void onPreDhcpAction() {}
         public void onPostDhcpAction() {}
 
@@ -113,6 +99,9 @@
         // Called when the internal IpReachabilityMonitor (if enabled) has
         // detected the loss of a critical number of required neighbors.
         public void onReachabilityLost(String logMsg) {}
+
+        // Called when the IpManager state machine terminates.
+        public void onQuit() {}
     }
 
     /**
@@ -201,7 +190,7 @@
      * Non-final member variables accessed only from within our StateMachine.
      */
     private IpReachabilityMonitor mIpReachabilityMonitor;
-    private BaseDhcpStateMachine mDhcpStateMachine;
+    private DhcpClient mDhcpClient;
     private DhcpResults mDhcpResults;
     private ProvisioningConfiguration mConfiguration;
 
@@ -269,6 +258,17 @@
         mNetlinkTracker = null;
     }
 
+    @Override
+    protected void onQuitting() {
+        mCallback.onQuit();
+    }
+
+    // Shut down this IpManager instance altogether.
+    public void shutdown() {
+        stop();
+        quit();
+    }
+
     public static ProvisioningConfiguration.Builder buildProvisioningConfiguration() {
         return new ProvisioningConfiguration.Builder();
     }
@@ -314,26 +314,7 @@
 
     @Override
     protected String getWhatToString(int what) {
-        // TODO: Investigate switching to reflection.
-        switch (what) {
-            case CMD_STOP:
-                return "CMD_STOP";
-            case CMD_START:
-                return "CMD_START";
-            case CMD_CONFIRM:
-                return "CMD_CONFIRM";
-            case EVENT_PRE_DHCP_ACTION_COMPLETE:
-                return "EVENT_PRE_DHCP_ACTION_COMPLETE";
-            case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
-                return "EVENT_NETLINK_LINKPROPERTIES_CHANGED";
-            case DhcpClient.CMD_PRE_DHCP_ACTION:
-                return "DhcpClient.CMD_PRE_DHCP_ACTION";
-            case DhcpClient.CMD_POST_DHCP_ACTION:
-                return "DhcpClient.CMD_POST_DHCP_ACTION";
-            case DhcpClient.CMD_ON_QUIT:
-                return "DhcpClient.CMD_ON_QUIT";
-        }
-        return "UNKNOWN:" + Integer.toString(what);
+        return sWhatToString.get(what, "UNKNOWN: " + Integer.toString(what));
     }
 
     @Override
@@ -624,7 +605,7 @@
     class StoppingState extends State {
         @Override
         public void enter() {
-            if (mDhcpStateMachine == null) {
+            if (mDhcpClient == null) {
                 // There's no DHCPv4 for which to wait; proceed to stopped.
                 transitionTo(mStoppedState);
             }
@@ -634,7 +615,7 @@
         public boolean processMessage(Message msg) {
             switch (msg.what) {
                 case DhcpClient.CMD_ON_QUIT:
-                    mDhcpStateMachine = null;
+                    mDhcpClient = null;
                     transitionTo(mStoppedState);
                     break;
 
@@ -683,9 +664,12 @@
                 }
             } else {
                 // Start DHCPv4.
-                makeDhcpStateMachine();
-                mDhcpStateMachine.registerForPreDhcpNotification();
-                mDhcpStateMachine.sendMessage(DhcpClient.CMD_START_DHCP);
+                mDhcpClient = DhcpClient.makeDhcpClient(
+                        mContext,
+                        IpManager.this,
+                        mInterfaceName);
+                mDhcpClient.registerForPreDhcpNotification();
+                mDhcpClient.sendMessage(DhcpClient.CMD_START_DHCP);
             }
         }
 
@@ -696,9 +680,9 @@
                 mIpReachabilityMonitor = null;
             }
 
-            if (mDhcpStateMachine != null) {
-                mDhcpStateMachine.sendMessage(DhcpClient.CMD_STOP_DHCP);
-                mDhcpStateMachine.doQuit();
+            if (mDhcpClient != null) {
+                mDhcpClient.sendMessage(DhcpClient.CMD_STOP_DHCP);
+                mDhcpClient.doQuit();
             }
 
             resetLinkProperties();
@@ -729,8 +713,8 @@
                     // It's possible to reach here if, for example, someone
                     // calls completedPreDhcpAction() after provisioning with
                     // a static IP configuration.
-                    if (mDhcpStateMachine != null) {
-                        mDhcpStateMachine.sendMessage(DhcpClient.CMD_PRE_DHCP_ACTION_COMPLETE);
+                    if (mDhcpClient != null) {
+                        mDhcpClient.sendMessage(DhcpClient.CMD_PRE_DHCP_ACTION_COMPLETE);
                     }
                     break;
 
@@ -780,7 +764,7 @@
                 case DhcpClient.CMD_ON_QUIT:
                     // DHCPv4 quit early for some reason.
                     Log.e(mTag, "Unexpected CMD_ON_QUIT.");
-                    mDhcpStateMachine = null;
+                    mDhcpClient = null;
                     break;
 
                 default:
@@ -803,23 +787,5 @@
 
             return true;
         }
-
-        private void makeDhcpStateMachine() {
-            final boolean usingLegacyDhcp = (Settings.Global.getInt(
-                    mContext.getContentResolver(),
-                    Settings.Global.LEGACY_DHCP_CLIENT, 0) == 1);
-
-            if (usingLegacyDhcp) {
-                mDhcpStateMachine = DhcpStateMachine.makeDhcpStateMachine(
-                        mContext,
-                        IpManager.this,
-                        mInterfaceName);
-            } else {
-                mDhcpStateMachine = DhcpClient.makeDhcpStateMachine(
-                        mContext,
-                        IpManager.this,
-                        mInterfaceName);
-            }
-        }
     }
 }
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index 44be671..2373754 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -155,10 +155,6 @@
      * Do not place scans in the chip's scan history buffer
      */
     public static final int REPORT_EVENT_NO_BATCH = (1 << 2);
-    /**
-     * report full scan results and completion event to the context hub
-     */
-    public static final int REPORT_EVENT_CONTEXT_HUB = (1 << 3);
 
     /**
      * scan configuration parameters to be sent to {@link #startBackgroundScan}
diff --git a/wifi/java/android/net/wifi/nan/IWifiNanEventListener.aidl b/wifi/java/android/net/wifi/nan/IWifiNanEventCallback.aidl
similarity index 95%
rename from wifi/java/android/net/wifi/nan/IWifiNanEventListener.aidl
rename to wifi/java/android/net/wifi/nan/IWifiNanEventCallback.aidl
index fa666af..c4ba928 100644
--- a/wifi/java/android/net/wifi/nan/IWifiNanEventListener.aidl
+++ b/wifi/java/android/net/wifi/nan/IWifiNanEventCallback.aidl
@@ -23,7 +23,7 @@
  *
  * {@hide}
  */
-oneway interface IWifiNanEventListener
+oneway interface IWifiNanEventCallback
 {
     void onConfigCompleted(in ConfigRequest completedConfig);
     void onConfigFailed(in ConfigRequest failedConfig, int reason);
diff --git a/wifi/java/android/net/wifi/nan/IWifiNanManager.aidl b/wifi/java/android/net/wifi/nan/IWifiNanManager.aidl
index f382d97..d1cf90d 100644
--- a/wifi/java/android/net/wifi/nan/IWifiNanManager.aidl
+++ b/wifi/java/android/net/wifi/nan/IWifiNanManager.aidl
@@ -19,12 +19,10 @@
 import android.app.PendingIntent;
 
 import android.net.wifi.nan.ConfigRequest;
-import android.net.wifi.nan.IWifiNanEventListener;
-import android.net.wifi.nan.IWifiNanSessionListener;
-import android.net.wifi.nan.PublishData;
-import android.net.wifi.nan.PublishSettings;
-import android.net.wifi.nan.SubscribeData;
-import android.net.wifi.nan.SubscribeSettings;
+import android.net.wifi.nan.IWifiNanEventCallback;
+import android.net.wifi.nan.IWifiNanSessionCallback;
+import android.net.wifi.nan.PublishConfig;
+import android.net.wifi.nan.SubscribeConfig;
 
 /**
  * Interface that WifiNanService implements
@@ -34,17 +32,16 @@
 interface IWifiNanManager
 {
     // client API
-    void connect(in IBinder binder, in IWifiNanEventListener listener, int events);
-    void disconnect(in IBinder binder);
-    void requestConfig(in ConfigRequest configRequest);
+    int connect(in IBinder binder, in IWifiNanEventCallback callback, int events);
+    void disconnect(int clientId, in IBinder binder);
+    void requestConfig(int clientId, in ConfigRequest configRequest);
 
     // session API
-    int createSession(in IWifiNanSessionListener listener, int events);
-    void publish(int sessionId, in PublishData publishData, in PublishSettings publishSettings);
-    void subscribe(int sessionId, in SubscribeData subscribeData,
-            in SubscribeSettings subscribeSettings);
-    void sendMessage(int sessionId, int peerId, in byte[] message, int messageLength,
+    int createSession(int clientId, in IWifiNanSessionCallback callback, int events);
+    void publish(int clientId, int sessionId, in PublishConfig publishConfig);
+    void subscribe(int clientId, int sessionId, in SubscribeConfig subscribeConfig);
+    void sendMessage(int clientId, int sessionId, int peerId, in byte[] message, int messageLength,
             int messageId);
-    void stopSession(int sessionId);
-    void destroySession(int sessionId);
+    void stopSession(int clientId, int sessionId);
+    void destroySession(int clientId, int sessionId);
 }
diff --git a/wifi/java/android/net/wifi/nan/IWifiNanSessionListener.aidl b/wifi/java/android/net/wifi/nan/IWifiNanSessionCallback.aidl
similarity index 96%
rename from wifi/java/android/net/wifi/nan/IWifiNanSessionListener.aidl
rename to wifi/java/android/net/wifi/nan/IWifiNanSessionCallback.aidl
index d60d8ca..c79f2f8 100644
--- a/wifi/java/android/net/wifi/nan/IWifiNanSessionListener.aidl
+++ b/wifi/java/android/net/wifi/nan/IWifiNanSessionCallback.aidl
@@ -21,7 +21,7 @@
  *
  * {@hide}
  */
-oneway interface IWifiNanSessionListener
+oneway interface IWifiNanSessionCallback
 {
     void onPublishFail(int reason);
     void onPublishTerminated(int reason);
diff --git a/wifi/java/android/net/wifi/nan/SubscribeSettings.aidl b/wifi/java/android/net/wifi/nan/PublishConfig.aidl
similarity index 95%
rename from wifi/java/android/net/wifi/nan/SubscribeSettings.aidl
rename to wifi/java/android/net/wifi/nan/PublishConfig.aidl
index 44849bc..5f66d16 100644
--- a/wifi/java/android/net/wifi/nan/SubscribeSettings.aidl
+++ b/wifi/java/android/net/wifi/nan/PublishConfig.aidl
@@ -16,4 +16,4 @@
 
 package android.net.wifi.nan;
 
-parcelable SubscribeSettings;
+parcelable PublishConfig;
diff --git a/wifi/java/android/net/wifi/nan/PublishData.java b/wifi/java/android/net/wifi/nan/PublishConfig.java
similarity index 63%
rename from wifi/java/android/net/wifi/nan/PublishData.java
rename to wifi/java/android/net/wifi/nan/PublishConfig.java
index 80119eb..cf5251c 100644
--- a/wifi/java/android/net/wifi/nan/PublishData.java
+++ b/wifi/java/android/net/wifi/nan/PublishConfig.java
@@ -22,13 +22,29 @@
 import java.util.Arrays;
 
 /**
- * Defines the data for a NAN publish session. Built using
- * {@link PublishData.Builder}. Publish is done using
- * {@link WifiNanManager#publish(PublishData, PublishSettings, WifiNanSessionListener, int)}
- * or {@link WifiNanPublishSession#publish(PublishData, PublishSettings)}.
+ * Defines the configuration of a NAN publish session. Built using
+ * {@link PublishConfig.Builder}. Publish is done using
+ * {@link WifiNanManager#publish(PublishConfig, WifiNanSessionListener, int)} or
+ * {@link WifiNanPublishSession#publish(PublishConfig)}.
+ *
  * @hide PROPOSED_NAN_API
  */
-public class PublishData implements Parcelable {
+public class PublishConfig implements Parcelable {
+    /**
+     * Defines an unsolicited publish session - i.e. a publish session where
+     * publish packets are transmitted over-the-air. Configuration is done using
+     * {@link PublishConfig.Builder#setPublishType(int)}.
+     */
+    public static final int PUBLISH_TYPE_UNSOLICITED = 0;
+
+    /**
+     * Defines a solicited publish session - i.e. a publish session where
+     * publish packets are not transmitted over-the-air and the device listens
+     * and matches to transmitted subscribe packets. Configuration is done using
+     * {@link PublishConfig.Builder#setPublishType(int)}.
+     */
+    public static final int PUBLISH_TYPE_SOLICITED = 1;
+
     /**
      * @hide
      */
@@ -64,9 +80,24 @@
      */
     public final byte[] mRxFilter;
 
-    private PublishData(String serviceName, byte[] serviceSpecificInfo,
+    /**
+     * @hide
+     */
+    public final int mPublishType;
+
+    /**
+     * @hide
+     */
+    public final int mPublishCount;
+
+    /**
+     * @hide
+     */
+    public final int mTtlSec;
+
+    private PublishConfig(String serviceName, byte[] serviceSpecificInfo,
             int serviceSpecificInfoLength, byte[] txFilter, int txFilterLength, byte[] rxFilter,
-            int rxFilterLength) {
+            int rxFilterLength, int publishType, int publichCount, int ttlSec) {
         mServiceName = serviceName;
         mServiceSpecificInfoLength = serviceSpecificInfoLength;
         mServiceSpecificInfo = serviceSpecificInfo;
@@ -74,17 +105,21 @@
         mTxFilter = txFilter;
         mRxFilterLength = rxFilterLength;
         mRxFilter = rxFilter;
+        mPublishType = publishType;
+        mPublishCount = publichCount;
+        mTtlSec = ttlSec;
     }
 
     @Override
     public String toString() {
-        return "PublishData [mServiceName='" + mServiceName + "', mServiceSpecificInfo='"
+        return "PublishConfig [mServiceName='" + mServiceName + "', mServiceSpecificInfo='"
                 + (new String(mServiceSpecificInfo, 0, mServiceSpecificInfoLength))
                 + "', mTxFilter="
                 + (new TlvBufferUtils.TlvIterable(0, 1, mTxFilter, mTxFilterLength)).toString()
                 + ", mRxFilter="
                 + (new TlvBufferUtils.TlvIterable(0, 1, mRxFilter, mRxFilterLength)).toString()
-                + "']";
+                + ", mPublishType=" + mPublishType + ", mPublishCount=" + mPublishCount
+                + ", mTtlSec=" + mTtlSec + "']";
     }
 
     @Override
@@ -92,7 +127,6 @@
         return 0;
     }
 
-
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeString(mServiceName);
@@ -108,16 +142,19 @@
         if (mRxFilterLength != 0) {
             dest.writeByteArray(mRxFilter, 0, mRxFilterLength);
         }
+        dest.writeInt(mPublishType);
+        dest.writeInt(mPublishCount);
+        dest.writeInt(mTtlSec);
     }
 
-    public static final Creator<PublishData> CREATOR = new Creator<PublishData>() {
+    public static final Creator<PublishConfig> CREATOR = new Creator<PublishConfig>() {
         @Override
-        public PublishData[] newArray(int size) {
-            return new PublishData[size];
+        public PublishConfig[] newArray(int size) {
+            return new PublishConfig[size];
         }
 
         @Override
-        public PublishData createFromParcel(Parcel in) {
+        public PublishConfig createFromParcel(Parcel in) {
             String serviceName = in.readString();
             int ssiLength = in.readInt();
             byte[] ssi = new byte[ssiLength];
@@ -134,9 +171,11 @@
             if (rxFilterLength != 0) {
                 in.readByteArray(rxFilter);
             }
-
-            return new PublishData(serviceName, ssi, ssiLength, txFilter, txFilterLength, rxFilter,
-                    rxFilterLength);
+            int publishType = in.readInt();
+            int publishCount = in.readInt();
+            int ttlSec = in.readInt();
+            return new PublishConfig(serviceName, ssi, ssiLength, txFilter, txFilterLength,
+                    rxFilter, rxFilterLength, publishType, publishCount, ttlSec);
         }
     };
 
@@ -146,11 +185,11 @@
             return true;
         }
 
-        if (!(o instanceof PublishData)) {
+        if (!(o instanceof PublishConfig)) {
             return false;
         }
 
-        PublishData lhs = (PublishData) o;
+        PublishConfig lhs = (PublishConfig) o;
 
         if (!mServiceName.equals(lhs.mServiceName)
                 || mServiceSpecificInfoLength != lhs.mServiceSpecificInfoLength
@@ -189,7 +228,8 @@
             return false; // invalid != invalid
         }
 
-        return true;
+        return mPublishType == lhs.mPublishType && mPublishCount == lhs.mPublishCount
+                && mTtlSec == lhs.mTtlSec;
     }
 
     @Override
@@ -203,12 +243,15 @@
         result = 31 * result + Arrays.hashCode(mTxFilter);
         result = 31 * result + mRxFilterLength;
         result = 31 * result + Arrays.hashCode(mRxFilter);
+        result = 31 * result + mPublishType;
+        result = 31 * result + mPublishCount;
+        result = 31 * result + mTtlSec;
 
         return result;
     }
 
     /**
-     * Builder used to build {@link PublishData} objects.
+     * Builder used to build {@link PublishConfig} objects.
      */
     public static final class Builder {
         private String mServiceName;
@@ -218,6 +261,9 @@
         private byte[] mTxFilter = new byte[0];
         private int mRxFilterLength;
         private byte[] mRxFilter = new byte[0];
+        private int mPublishType;
+        private int mPublishCount;
+        private int mTtlSec;
 
         /**
          * Specify the service name of the publish session. The actual on-air
@@ -260,7 +306,7 @@
 
         /**
          * Specify service specific information for the publish session - same
-         * as {@link PublishData.Builder#setServiceSpecificInfo(byte[], int)}
+         * as {@link PublishConfig.Builder#setServiceSpecificInfo(byte[], int)}
          * but obtaining the data from a String.
          *
          * @param serviceSpecificInfoStr The service specific information string
@@ -277,8 +323,8 @@
 
         /**
          * The transmit filter for an active publish session
-         * {@link PublishSettings.Builder#setPublishType(int)} and
-         * {@link PublishSettings#PUBLISH_TYPE_UNSOLICITED}. Included in
+         * {@link PublishConfig.Builder#setPublishType(int)} and
+         * {@link PublishConfig#PUBLISH_TYPE_UNSOLICITED}. Included in
          * transmitted publish packets and used by receivers (subscribers) to
          * determine whether they match - in addition to just relying on the
          * service name.
@@ -305,8 +351,8 @@
 
         /**
          * The transmit filter for a passive publish session
-         * {@link PublishSettings.Builder#setPublishType(int)} and
-         * {@link PublishSettings#PUBLISH_TYPE_SOLICITED}. Used by the publisher
+         * {@link PublishConfig.Builder#setPublishType(int)} and
+         * {@link PublishConfig#PUBLISH_TYPE_SOLICITED}. Used by the publisher
          * to determine whether they match transmitted subscriber packets
          * (active subscribers) - in addition to just relying on the service
          * name.
@@ -332,12 +378,73 @@
         }
 
         /**
-         * Build {@link PublishData} given the current requests made on the
+         * Sets the type of the publish session: solicited (aka active - publish
+         * packets are transmitted over-the-air), or unsolicited (aka passive -
+         * no publish packets are transmitted, a match is made against an active
+         * subscribe session whose packets are transmitted over-the-air).
+         *
+         * @param publishType Publish session type: solicited (
+         *            {@link PublishConfig#PUBLISH_TYPE_SOLICITED}) or
+         *            unsolicited (
+         *            {@link PublishConfig#PUBLISH_TYPE_UNSOLICITED}).
+         * @return The builder to facilitate chaining
+         *         {@code builder.setXXX(..).setXXX(..)}.
+         */
+        public Builder setPublishType(int publishType) {
+            if (publishType < PUBLISH_TYPE_UNSOLICITED || publishType > PUBLISH_TYPE_SOLICITED) {
+                throw new IllegalArgumentException("Invalid publishType - " + publishType);
+            }
+            mPublishType = publishType;
+            return this;
+        }
+
+        /**
+         * Sets the number of times a solicited (
+         * {@link PublishConfig.Builder#setPublishType(int)}) publish session
+         * will transmit a packet. When the count is reached an event will be
+         * generated for {@link WifiNanSessionListener#onPublishTerminated(int)}
+         * with reason={@link WifiNanSessionListener#TERMINATE_REASON_DONE}.
+         *
+         * @param publishCount Number of publish packets to transmit.
+         * @return The builder to facilitate chaining
+         *         {@code builder.setXXX(..).setXXX(..)}.
+         */
+        public Builder setPublishCount(int publishCount) {
+            if (publishCount < 0) {
+                throw new IllegalArgumentException("Invalid publishCount - must be non-negative");
+            }
+            mPublishCount = publishCount;
+            return this;
+        }
+
+        /**
+         * Sets the time interval (in seconds) a solicited (
+         * {@link PublishConfig.Builder#setPublishCount(int)}) publish session
+         * will be alive - i.e. transmitting a packet. When the TTL is reached
+         * an event will be generated for
+         * {@link WifiNanSessionListener#onPublishTerminated(int)} with reason=
+         * {@link WifiNanSessionListener#TERMINATE_REASON_DONE}.
+         *
+         * @param ttlSec Lifetime of a publish session in seconds.
+         * @return The builder to facilitate chaining
+         *         {@code builder.setXXX(..).setXXX(..)}.
+         */
+        public Builder setTtlSec(int ttlSec) {
+            if (ttlSec < 0) {
+                throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
+            }
+            mTtlSec = ttlSec;
+            return this;
+        }
+
+        /**
+         * Build {@link PublishConfig} given the current requests made on the
          * builder.
          */
-        public PublishData build() {
-            return new PublishData(mServiceName, mServiceSpecificInfo, mServiceSpecificInfoLength,
-                    mTxFilter, mTxFilterLength, mRxFilter, mRxFilterLength);
+        public PublishConfig build() {
+            return new PublishConfig(mServiceName, mServiceSpecificInfo, mServiceSpecificInfoLength,
+                    mTxFilter, mTxFilterLength, mRxFilter, mRxFilterLength, mPublishType,
+                    mPublishCount, mTtlSec);
         }
     }
 }
diff --git a/wifi/java/android/net/wifi/nan/PublishData.aidl b/wifi/java/android/net/wifi/nan/PublishData.aidl
deleted file mode 100644
index 15e4ddf..0000000
--- a/wifi/java/android/net/wifi/nan/PublishData.aidl
+++ /dev/null
@@ -1,19 +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 android.net.wifi.nan;
-
-parcelable PublishData;
diff --git a/wifi/java/android/net/wifi/nan/PublishSettings.aidl b/wifi/java/android/net/wifi/nan/PublishSettings.aidl
deleted file mode 100644
index ff69293..0000000
--- a/wifi/java/android/net/wifi/nan/PublishSettings.aidl
+++ /dev/null
@@ -1,19 +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 android.net.wifi.nan;
-
-parcelable PublishSettings;
diff --git a/wifi/java/android/net/wifi/nan/PublishSettings.java b/wifi/java/android/net/wifi/nan/PublishSettings.java
deleted file mode 100644
index bbc5340..0000000
--- a/wifi/java/android/net/wifi/nan/PublishSettings.java
+++ /dev/null
@@ -1,204 +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 android.net.wifi.nan;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Defines the settings (configuration) for a NAN publish session. Built using
- * {@link PublishSettings.Builder}. Publish is done using
- * {@link WifiNanManager#publish(PublishData, PublishSettings, WifiNanSessionListener, int)}
- * or {@link WifiNanPublishSession#publish(PublishData, PublishSettings)}.
- *
- * @hide PROPOSED_NAN_API
- */
-public class PublishSettings implements Parcelable {
-
-    /**
-     * Defines an unsolicited publish session - i.e. a publish session where
-     * publish packets are transmitted over-the-air. Configuration is done using
-     * {@link PublishSettings.Builder#setPublishType(int)}.
-     */
-    public static final int PUBLISH_TYPE_UNSOLICITED = 0;
-
-    /**
-     * Defines a solicited publish session - i.e. a publish session where
-     * publish packets are not transmitted over-the-air and the device listens
-     * and matches to transmitted subscribe packets. Configuration is done using
-     * {@link PublishSettings.Builder#setPublishType(int)}.
-     */
-    public static final int PUBLISH_TYPE_SOLICITED = 1;
-
-    /**
-     * @hide
-     */
-    public final int mPublishType;
-
-    /**
-     * @hide
-     */
-    public final int mPublishCount;
-
-    /**
-     * @hide
-     */
-    public final int mTtlSec;
-
-    private PublishSettings(int publishType, int publichCount, int ttlSec) {
-        mPublishType = publishType;
-        mPublishCount = publichCount;
-        mTtlSec = ttlSec;
-    }
-
-    @Override
-    public String toString() {
-        return "PublishSettings [mPublishType=" + mPublishType + ", mPublishCount=" + mPublishCount
-                + ", mTtlSec=" + mTtlSec + "]";
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mPublishType);
-        dest.writeInt(mPublishCount);
-        dest.writeInt(mTtlSec);
-    }
-
-    public static final Creator<PublishSettings> CREATOR = new Creator<PublishSettings>() {
-        @Override
-        public PublishSettings[] newArray(int size) {
-            return new PublishSettings[size];
-        }
-
-        @Override
-        public PublishSettings createFromParcel(Parcel in) {
-            int publishType = in.readInt();
-            int publishCount = in.readInt();
-            int ttlSec = in.readInt();
-            return new PublishSettings(publishType, publishCount, ttlSec);
-        }
-    };
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-
-        if (!(o instanceof PublishSettings)) {
-            return false;
-        }
-
-        PublishSettings lhs = (PublishSettings) o;
-
-        return mPublishType == lhs.mPublishType && mPublishCount == lhs.mPublishCount
-                && mTtlSec == lhs.mTtlSec;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = 17;
-
-        result = 31 * result + mPublishType;
-        result = 31 * result + mPublishCount;
-        result = 31 * result + mTtlSec;
-
-        return result;
-    }
-
-    /**
-     * Builder used to build {@link PublishSettings} objects.
-     */
-    public static final class Builder {
-        int mPublishType;
-        int mPublishCount;
-        int mTtlSec;
-
-        /**
-         * Sets the type of the publish session: solicited (aka active - publish
-         * packets are transmitted over-the-air), or unsolicited (aka passive -
-         * no publish packets are transmitted, a match is made against an active
-         * subscribe session whose packets are transmitted over-the-air).
-         *
-         * @param publishType Publish session type: solicited (
-         *            {@link PublishSettings#PUBLISH_TYPE_SOLICITED}) or
-         *            unsolicited (
-         *            {@link PublishSettings#PUBLISH_TYPE_UNSOLICITED}).
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder setPublishType(int publishType) {
-            if (publishType < PUBLISH_TYPE_UNSOLICITED || publishType > PUBLISH_TYPE_SOLICITED) {
-                throw new IllegalArgumentException("Invalid publishType - " + publishType);
-            }
-            mPublishType = publishType;
-            return this;
-        }
-
-        /**
-         * Sets the number of times a solicited (
-         * {@link PublishSettings.Builder#setPublishType(int)}) publish session
-         * will transmit a packet. When the count is reached an event will be
-         * generated for {@link WifiNanSessionListener#onPublishTerminated(int)}
-         * with reason={@link WifiNanSessionListener#TERMINATE_REASON_DONE}.
-         *
-         * @param publishCount Number of publish packets to transmit.
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder setPublishCount(int publishCount) {
-            if (publishCount < 0) {
-                throw new IllegalArgumentException("Invalid publishCount - must be non-negative");
-            }
-            mPublishCount = publishCount;
-            return this;
-        }
-
-        /**
-         * Sets the time interval (in seconds) a solicited (
-         * {@link PublishSettings.Builder#setPublishCount(int)}) publish session
-         * will be alive - i.e. transmitting a packet. When the TTL is reached
-         * an event will be generated for
-         * {@link WifiNanSessionListener#onPublishTerminated(int)} with reason=
-         * {@link WifiNanSessionListener#TERMINATE_REASON_DONE}.
-         *
-         * @param ttlSec Lifetime of a publish session in seconds.
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder setTtlSec(int ttlSec) {
-            if (ttlSec < 0) {
-                throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
-            }
-            mTtlSec = ttlSec;
-            return this;
-        }
-
-        /**
-         * Build {@link PublishSettings} given the current requests made on the
-         * builder.
-         */
-        public PublishSettings build() {
-            return new PublishSettings(mPublishType, mPublishCount, mTtlSec);
-        }
-    }
-}
diff --git a/wifi/java/android/net/wifi/nan/SubscribeSettings.aidl b/wifi/java/android/net/wifi/nan/SubscribeConfig.aidl
similarity index 95%
copy from wifi/java/android/net/wifi/nan/SubscribeSettings.aidl
copy to wifi/java/android/net/wifi/nan/SubscribeConfig.aidl
index 44849bc..92344a4 100644
--- a/wifi/java/android/net/wifi/nan/SubscribeSettings.aidl
+++ b/wifi/java/android/net/wifi/nan/SubscribeConfig.aidl
@@ -16,4 +16,4 @@
 
 package android.net.wifi.nan;
 
-parcelable SubscribeSettings;
+parcelable SubscribeConfig;
diff --git a/wifi/java/android/net/wifi/nan/SubscribeData.java b/wifi/java/android/net/wifi/nan/SubscribeConfig.java
similarity index 60%
rename from wifi/java/android/net/wifi/nan/SubscribeData.java
rename to wifi/java/android/net/wifi/nan/SubscribeConfig.java
index cd6e918..4798293 100644
--- a/wifi/java/android/net/wifi/nan/SubscribeData.java
+++ b/wifi/java/android/net/wifi/nan/SubscribeConfig.java
@@ -22,14 +22,30 @@
 import java.util.Arrays;
 
 /**
- * Defines the data for a NAN subscribe session. Built using
- * {@link SubscribeData.Builder}. Subscribe is done using
- * {@link WifiNanManager#subscribe(SubscribeData, SubscribeSettings, WifiNanSessionListener, int)}
- * or
- * {@link WifiNanSubscribeSession#subscribe(SubscribeData, SubscribeSettings)}.
+ * Defines the configuration of a NAN subscribe session. Built using
+ * {@link SubscribeConfig.Builder}. Subscribe is done using
+ * {@link WifiNanManager#subscribe(SubscribeConfig, WifiNanSessionListener, int)}
+ * or {@link WifiNanSubscribeSession#subscribe(SubscribeConfig)}.
+ *
  * @hide PROPOSED_NAN_API
  */
-public class SubscribeData implements Parcelable {
+public class SubscribeConfig implements Parcelable {
+
+    /**
+     * Defines a passive subscribe session - i.e. a subscribe session where
+     * subscribe packets are not transmitted over-the-air and the device listens
+     * and matches to transmitted publish packets. Configuration is done using
+     * {@link SubscribeConfig.Builder#setSubscribeType(int)}.
+     */
+    public static final int SUBSCRIBE_TYPE_PASSIVE = 0;
+
+    /**
+     * Defines an active subscribe session - i.e. a subscribe session where
+     * subscribe packets are transmitted over-the-air. Configuration is done
+     * using {@link SubscribeConfig.Builder#setSubscribeType(int)}.
+     */
+    public static final int SUBSCRIBE_TYPE_ACTIVE = 1;
+
     /**
      * @hide
      */
@@ -65,9 +81,24 @@
      */
     public final byte[] mRxFilter;
 
-    private SubscribeData(String serviceName, byte[] serviceSpecificInfo,
+    /**
+     * @hide
+     */
+    public final int mSubscribeType;
+
+    /**
+     * @hide
+     */
+    public final int mSubscribeCount;
+
+    /**
+     * @hide
+     */
+    public final int mTtlSec;
+
+    private SubscribeConfig(String serviceName, byte[] serviceSpecificInfo,
             int serviceSpecificInfoLength, byte[] txFilter, int txFilterLength, byte[] rxFilter,
-            int rxFilterLength) {
+            int rxFilterLength, int subscribeType, int publichCount, int ttlSec) {
         mServiceName = serviceName;
         mServiceSpecificInfoLength = serviceSpecificInfoLength;
         mServiceSpecificInfo = serviceSpecificInfo;
@@ -75,17 +106,21 @@
         mTxFilter = txFilter;
         mRxFilterLength = rxFilterLength;
         mRxFilter = rxFilter;
+        mSubscribeType = subscribeType;
+        mSubscribeCount = publichCount;
+        mTtlSec = ttlSec;
     }
 
     @Override
     public String toString() {
-        return "SubscribeData [mServiceName='" + mServiceName + "', mServiceSpecificInfo='"
+        return "SubscribeConfig [mServiceName='" + mServiceName + "', mServiceSpecificInfo='"
                 + (new String(mServiceSpecificInfo, 0, mServiceSpecificInfoLength))
                 + "', mTxFilter="
                 + (new TlvBufferUtils.TlvIterable(0, 1, mTxFilter, mTxFilterLength)).toString()
                 + ", mRxFilter="
                 + (new TlvBufferUtils.TlvIterable(0, 1, mRxFilter, mRxFilterLength)).toString()
-                + "']";
+                + ", mSubscribeType=" + mSubscribeType + ", mSubscribeCount=" + mSubscribeCount
+                + ", mTtlSec=" + mTtlSec + "']";
     }
 
     @Override
@@ -108,16 +143,19 @@
         if (mRxFilterLength != 0) {
             dest.writeByteArray(mRxFilter, 0, mRxFilterLength);
         }
+        dest.writeInt(mSubscribeType);
+        dest.writeInt(mSubscribeCount);
+        dest.writeInt(mTtlSec);
     }
 
-    public static final Creator<SubscribeData> CREATOR = new Creator<SubscribeData>() {
+    public static final Creator<SubscribeConfig> CREATOR = new Creator<SubscribeConfig>() {
         @Override
-        public SubscribeData[] newArray(int size) {
-            return new SubscribeData[size];
+        public SubscribeConfig[] newArray(int size) {
+            return new SubscribeConfig[size];
         }
 
         @Override
-        public SubscribeData createFromParcel(Parcel in) {
+        public SubscribeConfig createFromParcel(Parcel in) {
             String serviceName = in.readString();
             int ssiLength = in.readInt();
             byte[] ssi = new byte[ssiLength];
@@ -134,9 +172,11 @@
             if (rxFilterLength != 0) {
                 in.readByteArray(rxFilter);
             }
-
-            return new SubscribeData(serviceName, ssi, ssiLength, txFilter, txFilterLength,
-                    rxFilter, rxFilterLength);
+            int subscribeType = in.readInt();
+            int subscribeCount = in.readInt();
+            int ttlSec = in.readInt();
+            return new SubscribeConfig(serviceName, ssi, ssiLength, txFilter, txFilterLength,
+                    rxFilter, rxFilterLength, subscribeType, subscribeCount, ttlSec);
         }
     };
 
@@ -146,11 +186,11 @@
             return true;
         }
 
-        if (!(o instanceof SubscribeData)) {
+        if (!(o instanceof SubscribeConfig)) {
             return false;
         }
 
-        SubscribeData lhs = (SubscribeData) o;
+        SubscribeConfig lhs = (SubscribeConfig) o;
 
         if (!mServiceName.equals(lhs.mServiceName)
                 || mServiceSpecificInfoLength != lhs.mServiceSpecificInfoLength
@@ -189,7 +229,8 @@
             return false; // invalid != invalid
         }
 
-        return true;
+        return mSubscribeType == lhs.mSubscribeType && mSubscribeCount == lhs.mSubscribeCount
+                && mTtlSec == lhs.mTtlSec;
     }
 
     @Override
@@ -203,12 +244,15 @@
         result = 31 * result + Arrays.hashCode(mTxFilter);
         result = 31 * result + mRxFilterLength;
         result = 31 * result + Arrays.hashCode(mRxFilter);
+        result = 31 * result + mSubscribeType;
+        result = 31 * result + mSubscribeCount;
+        result = 31 * result + mTtlSec;
 
         return result;
     }
 
     /**
-     * Builder used to build {@link SubscribeData} objects.
+     * Builder used to build {@link SubscribeConfig} objects.
      */
     public static final class Builder {
         private String mServiceName;
@@ -218,6 +262,9 @@
         private byte[] mTxFilter = new byte[0];
         private int mRxFilterLength;
         private byte[] mRxFilter = new byte[0];
+        private int mSubscribeType;
+        private int mSubscribeCount;
+        private int mTtlSec;
 
         /**
          * Specify the service name of the subscribe session. The actual on-air
@@ -255,7 +302,8 @@
 
         /**
          * Specify service specific information for the subscribe session - same
-         * as {@link SubscribeData.Builder#setServiceSpecificInfo(byte[], int)}
+         * as
+         * {@link SubscribeConfig.Builder#setServiceSpecificInfo(byte[], int)}
          * but obtaining the data from a String.
          *
          * @param serviceSpecificInfoStr The service specific information string
@@ -272,8 +320,8 @@
 
         /**
          * The transmit filter for an active subscribe session
-         * {@link SubscribeSettings.Builder#setSubscribeType(int)} and
-         * {@link SubscribeSettings#SUBSCRIBE_TYPE_ACTIVE}. Included in
+         * {@link SubscribeConfig.Builder#setSubscribeType(int)} and
+         * {@link SubscribeConfig#SUBSCRIBE_TYPE_ACTIVE}. Included in
          * transmitted subscribe packets and used by receivers (passive
          * publishers) to determine whether they match - in addition to just
          * relying on the service name.
@@ -296,8 +344,8 @@
 
         /**
          * The transmit filter for a passive subsribe session
-         * {@link SubscribeSettings.Builder#setSubscribeType(int)} and
-         * {@link SubscribeSettings#SUBSCRIBE_TYPE_PASSIVE}. Used by the
+         * {@link SubscribeConfig.Builder#setSubscribeType(int)} and
+         * {@link SubscribeConfig#SUBSCRIBE_TYPE_PASSIVE}. Used by the
          * subscriber to determine whether they match transmitted publish
          * packets - in addition to just relying on the service name.
          * <p>
@@ -318,12 +366,73 @@
         }
 
         /**
-         * Build {@link SubscribeData} given the current requests made on the
+         * Sets the type of the subscribe session: active (subscribe packets are
+         * transmitted over-the-air), or passive (no subscribe packets are
+         * transmitted, a match is made against a solicited/active publish
+         * session whose packets are transmitted over-the-air).
+         *
+         * @param subscribeType Subscribe session type: active (
+         *            {@link SubscribeConfig#SUBSCRIBE_TYPE_ACTIVE}) or passive
+         *            ( {@link SubscribeConfig#SUBSCRIBE_TYPE_PASSIVE} ).
+         * @return The builder to facilitate chaining
+         *         {@code builder.setXXX(..).setXXX(..)}.
+         */
+        public Builder setSubscribeType(int subscribeType) {
+            if (subscribeType < SUBSCRIBE_TYPE_PASSIVE || subscribeType > SUBSCRIBE_TYPE_ACTIVE) {
+                throw new IllegalArgumentException("Invalid subscribeType - " + subscribeType);
+            }
+            mSubscribeType = subscribeType;
+            return this;
+        }
+
+        /**
+         * Sets the number of times an active (
+         * {@link SubscribeConfig.Builder#setSubscribeType(int)}) subscribe
+         * session will transmit a packet. When the count is reached an event
+         * will be generated for
+         * {@link WifiNanSessionListener#onSubscribeTerminated(int)} with
+         * reason= {@link WifiNanSessionListener#TERMINATE_REASON_DONE}.
+         *
+         * @param subscribeCount Number of subscribe packets to transmit.
+         * @return The builder to facilitate chaining
+         *         {@code builder.setXXX(..).setXXX(..)}.
+         */
+        public Builder setSubscribeCount(int subscribeCount) {
+            if (subscribeCount < 0) {
+                throw new IllegalArgumentException("Invalid subscribeCount - must be non-negative");
+            }
+            mSubscribeCount = subscribeCount;
+            return this;
+        }
+
+        /**
+         * Sets the time interval (in seconds) an active (
+         * {@link SubscribeConfig.Builder#setSubscribeType(int)}) subscribe
+         * session will be alive - i.e. transmitting a packet. When the TTL is
+         * reached an event will be generated for
+         * {@link WifiNanSessionListener#onSubscribeTerminated(int)} with
+         * reason= {@link WifiNanSessionListener#TERMINATE_REASON_DONE}.
+         *
+         * @param ttlSec Lifetime of a subscribe session in seconds.
+         * @return The builder to facilitate chaining
+         *         {@code builder.setXXX(..).setXXX(..)}.
+         */
+        public Builder setTtlSec(int ttlSec) {
+            if (ttlSec < 0) {
+                throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
+            }
+            mTtlSec = ttlSec;
+            return this;
+        }
+
+        /**
+         * Build {@link SubscribeConfig} given the current requests made on the
          * builder.
          */
-        public SubscribeData build() {
-            return new SubscribeData(mServiceName, mServiceSpecificInfo, mServiceSpecificInfoLength,
-                    mTxFilter, mTxFilterLength, mRxFilter, mRxFilterLength);
+        public SubscribeConfig build() {
+            return new SubscribeConfig(mServiceName, mServiceSpecificInfo,
+                    mServiceSpecificInfoLength, mTxFilter, mTxFilterLength, mRxFilter,
+                    mRxFilterLength, mSubscribeType, mSubscribeCount, mTtlSec);
         }
     }
 }
diff --git a/wifi/java/android/net/wifi/nan/SubscribeData.aidl b/wifi/java/android/net/wifi/nan/SubscribeData.aidl
deleted file mode 100644
index 662fdb8..0000000
--- a/wifi/java/android/net/wifi/nan/SubscribeData.aidl
+++ /dev/null
@@ -1,19 +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 android.net.wifi.nan;
-
-parcelable SubscribeData;
diff --git a/wifi/java/android/net/wifi/nan/SubscribeSettings.java b/wifi/java/android/net/wifi/nan/SubscribeSettings.java
deleted file mode 100644
index 5c4f8fb..0000000
--- a/wifi/java/android/net/wifi/nan/SubscribeSettings.java
+++ /dev/null
@@ -1,205 +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 android.net.wifi.nan;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Defines the settings (configuration) for a NAN subscribe session. Built using
- * {@link SubscribeSettings.Builder}. Subscribe is done using
- * {@link WifiNanManager#subscribe(SubscribeData, SubscribeSettings, WifiNanSessionListener, int)}
- * or {@link WifiNanSubscribeSession#subscribe(SubscribeData, SubscribeSettings)}.
- *
- * @hide PROPOSED_NAN_API
- */
-public class SubscribeSettings implements Parcelable {
-
-    /**
-     * Defines a passive subscribe session - i.e. a subscribe session where
-     * subscribe packets are not transmitted over-the-air and the device listens
-     * and matches to transmitted publish packets. Configuration is done using
-     * {@link SubscribeSettings.Builder#setSubscribeType(int)}.
-     */
-    public static final int SUBSCRIBE_TYPE_PASSIVE = 0;
-
-    /**
-     * Defines an active subscribe session - i.e. a subscribe session where
-     * subscribe packets are transmitted over-the-air. Configuration is done
-     * using {@link SubscribeSettings.Builder#setSubscribeType(int)}.
-     */
-    public static final int SUBSCRIBE_TYPE_ACTIVE = 1;
-
-    /**
-     * @hide
-     */
-    public final int mSubscribeType;
-
-    /**
-     * @hide
-     */
-    public final int mSubscribeCount;
-
-    /**
-     * @hide
-     */
-    public final int mTtlSec;
-
-    private SubscribeSettings(int subscribeType, int publichCount, int ttlSec) {
-        mSubscribeType = subscribeType;
-        mSubscribeCount = publichCount;
-        mTtlSec = ttlSec;
-    }
-
-    @Override
-    public String toString() {
-        return "SubscribeSettings [mSubscribeType=" + mSubscribeType + ", mSubscribeCount="
-                + mSubscribeCount + ", mTtlSec=" + mTtlSec + "]";
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mSubscribeType);
-        dest.writeInt(mSubscribeCount);
-        dest.writeInt(mTtlSec);
-    }
-
-    public static final Creator<SubscribeSettings> CREATOR = new Creator<SubscribeSettings>() {
-        @Override
-        public SubscribeSettings[] newArray(int size) {
-            return new SubscribeSettings[size];
-        }
-
-        @Override
-        public SubscribeSettings createFromParcel(Parcel in) {
-            int subscribeType = in.readInt();
-            int subscribeCount = in.readInt();
-            int ttlSec = in.readInt();
-            return new SubscribeSettings(subscribeType, subscribeCount, ttlSec);
-        }
-    };
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-
-        if (!(o instanceof SubscribeSettings)) {
-            return false;
-        }
-
-        SubscribeSettings lhs = (SubscribeSettings) o;
-
-        return mSubscribeType == lhs.mSubscribeType && mSubscribeCount == lhs.mSubscribeCount
-                && mTtlSec == lhs.mTtlSec;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = 17;
-
-        result = 31 * result + mSubscribeType;
-        result = 31 * result + mSubscribeCount;
-        result = 31 * result + mTtlSec;
-
-        return result;
-    }
-
-    /**
-     * Builder used to build {@link SubscribeSettings} objects.
-     */
-    public static final class Builder {
-        int mSubscribeType;
-        int mSubscribeCount;
-        int mTtlSec;
-
-        /**
-         * Sets the type of the subscribe session: active (subscribe packets are
-         * transmitted over-the-air), or passive (no subscribe packets are
-         * transmitted, a match is made against a solicited/active publish
-         * session whose packets are transmitted over-the-air).
-         *
-         * @param subscribeType Subscribe session type: active (
-         *            {@link SubscribeSettings#SUBSCRIBE_TYPE_ACTIVE}) or
-         *            passive ( {@link SubscribeSettings#SUBSCRIBE_TYPE_PASSIVE}
-         *            ).
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder setSubscribeType(int subscribeType) {
-            if (subscribeType < SUBSCRIBE_TYPE_PASSIVE || subscribeType > SUBSCRIBE_TYPE_ACTIVE) {
-                throw new IllegalArgumentException("Invalid subscribeType - " + subscribeType);
-            }
-            mSubscribeType = subscribeType;
-            return this;
-        }
-
-        /**
-         * Sets the number of times an active (
-         * {@link SubscribeSettings.Builder#setSubscribeType(int)}) subscribe
-         * session will transmit a packet. When the count is reached an event
-         * will be generated for
-         * {@link WifiNanSessionListener#onSubscribeTerminated(int)} with reason=
-         * {@link WifiNanSessionListener#TERMINATE_REASON_DONE}.
-         *
-         * @param subscribeCount Number of subscribe packets to transmit.
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder setSubscribeCount(int subscribeCount) {
-            if (subscribeCount < 0) {
-                throw new IllegalArgumentException("Invalid subscribeCount - must be non-negative");
-            }
-            mSubscribeCount = subscribeCount;
-            return this;
-        }
-
-        /**
-         * Sets the time interval (in seconds) an active (
-         * {@link SubscribeSettings.Builder#setSubscribeType(int)}) subscribe
-         * session will be alive - i.e. transmitting a packet. When the TTL is
-         * reached an event will be generated for
-         * {@link WifiNanSessionListener#onSubscribeTerminated(int)} with reason=
-         * {@link WifiNanSessionListener#TERMINATE_REASON_DONE}.
-         *
-         * @param ttlSec Lifetime of a subscribe session in seconds.
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder setTtlSec(int ttlSec) {
-            if (ttlSec < 0) {
-                throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
-            }
-            mTtlSec = ttlSec;
-            return this;
-        }
-
-        /**
-         * Build {@link SubscribeSettings} given the current requests made on
-         * the builder.
-         */
-        public SubscribeSettings build() {
-            return new SubscribeSettings(mSubscribeType, mSubscribeCount, mTtlSec);
-        }
-    }
-}
diff --git a/wifi/java/android/net/wifi/nan/WifiNanEventListener.java b/wifi/java/android/net/wifi/nan/WifiNanEventCallback.java
similarity index 77%
rename from wifi/java/android/net/wifi/nan/WifiNanEventListener.java
rename to wifi/java/android/net/wifi/nan/WifiNanEventCallback.java
index 9e6ed4e..0929402 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanEventListener.java
+++ b/wifi/java/android/net/wifi/nan/WifiNanEventCallback.java
@@ -25,36 +25,37 @@
  * Base class for NAN events callbacks. Should be extended by applications
  * wanting notifications. These are callbacks applying to the NAN connection as
  * a whole - not to specific publish or subscribe sessions - for that see
- * {@link WifiNanSessionListener}.
+ * {@link WifiNanSessionCallback}.
  * <p>
  * During registration specify which specific events are desired using a set of
- * {@code NanEventListener.LISTEN_*} flags OR'd together. Only those events will
- * be delivered to the registered listener. Override those callbacks
- * {@code NanEventListener.on*} for the registered events.
+ * {@code NanEventCallback.LISTEN_*} flags OR'd together. Only those events will
+ * be delivered to the registered callback. Override those callbacks
+ * {@code WifiNanEventCallback.on*} for the registered events.
  *
  * @hide PROPOSED_NAN_API
  */
-public class WifiNanEventListener {
-    private static final String TAG = "WifiNanEventListener";
+public class WifiNanEventCallback {
+    private static final String TAG = "WifiNanEventCallback";
     private static final boolean DBG = false;
     private static final boolean VDBG = false; // STOPSHIP if true
 
     /**
      * Configuration completion callback event registration flag. Corresponding
-     * callback is {@link WifiNanEventListener#onConfigCompleted(ConfigRequest)}.
+     * callback is {@link WifiNanEventCallback#onConfigCompleted(ConfigRequest)}
+     * .
      */
     public static final int LISTEN_CONFIG_COMPLETED = 0x1 << 0;
 
     /**
      * Configuration failed callback event registration flag. Corresponding
      * callback is
-     * {@link WifiNanEventListener#onConfigFailed(ConfigRequest, int)}.
+     * {@link WifiNanEventCallback#onConfigFailed(ConfigRequest, int)}.
      */
     public static final int LISTEN_CONFIG_FAILED = 0x1 << 1;
 
     /**
      * NAN cluster is down callback event registration flag. Corresponding
-     * callback is {@link WifiNanEventListener#onNanDown(int)}.
+     * callback is {@link WifiNanEventCallback#onNanDown(int)}.
      */
     public static final int LISTEN_NAN_DOWN = 0x1 << 2;
 
@@ -63,27 +64,27 @@
      * joining a cluster, starting a cluster, or discovery interface change. The
      * implication is that peers you've been communicating with may no longer
      * recognize you and you need to re-establish your identity. Corresponding
-     * callback is {@link WifiNanEventListener#onIdentityChanged()}.
+     * callback is {@link WifiNanEventCallback#onIdentityChanged()}.
      */
     public static final int LISTEN_IDENTITY_CHANGED = 0x1 << 3;
 
     private final Handler mHandler;
 
     /**
-     * Constructs a {@link WifiNanEventListener} using the looper of the current
+     * Constructs a {@link WifiNanEventCallback} using the looper of the current
      * thread. I.e. all callbacks will be delivered on the current thread.
      */
-    public WifiNanEventListener() {
+    public WifiNanEventCallback() {
         this(Looper.myLooper());
     }
 
     /**
-     * Constructs a {@link WifiNanEventListener} using the specified looper. I.e.
-     * all callbacks will delivered on the thread of the specified looper.
+     * Constructs a {@link WifiNanEventCallback} using the specified looper.
+     * I.e. all callbacks will delivered on the thread of the specified looper.
      *
      * @param looper The looper on which to execute the callbacks.
      */
-    public WifiNanEventListener(Looper looper) {
+    public WifiNanEventCallback(Looper looper) {
         if (VDBG) Log.v(TAG, "ctor: looper=" + looper);
         mHandler = new Handler(looper) {
             @Override
@@ -91,16 +92,16 @@
                 if (DBG) Log.d(TAG, "What=" + msg.what + ", msg=" + msg);
                 switch (msg.what) {
                     case LISTEN_CONFIG_COMPLETED:
-                        WifiNanEventListener.this.onConfigCompleted((ConfigRequest) msg.obj);
+                        WifiNanEventCallback.this.onConfigCompleted((ConfigRequest) msg.obj);
                         break;
                     case LISTEN_CONFIG_FAILED:
-                        WifiNanEventListener.this.onConfigFailed((ConfigRequest) msg.obj, msg.arg1);
+                        WifiNanEventCallback.this.onConfigFailed((ConfigRequest) msg.obj, msg.arg1);
                         break;
                     case LISTEN_NAN_DOWN:
-                        WifiNanEventListener.this.onNanDown(msg.arg1);
+                        WifiNanEventCallback.this.onNanDown(msg.arg1);
                         break;
                     case LISTEN_IDENTITY_CHANGED:
-                        WifiNanEventListener.this.onIdentityChanged();
+                        WifiNanEventCallback.this.onIdentityChanged();
                         break;
                 }
             }
@@ -109,8 +110,8 @@
 
     /**
      * Called when NAN configuration is completed. Event will only be delivered
-     * if registered using {@link WifiNanEventListener#LISTEN_CONFIG_COMPLETED}. A
-     * dummy (empty implementation printing out a warning). Make sure to
+     * if registered using {@link WifiNanEventCallback#LISTEN_CONFIG_COMPLETED}.
+     * A dummy (empty implementation printing out a warning). Make sure to
      * override if registered.
      *
      * @param completedConfig The actual configuration request which was
@@ -124,11 +125,12 @@
 
     /**
      * Called when NAN configuration failed. Event will only be delivered if
-     * registered using {@link WifiNanEventListener#LISTEN_CONFIG_FAILED}. A dummy
-     * (empty implementation printing out a warning). Make sure to override if
-     * registered.
+     * registered using {@link WifiNanEventCallback#LISTEN_CONFIG_FAILED}. A
+     * dummy (empty implementation printing out a warning). Make sure to
+     * override if registered.
      *
-     * @param reason Failure reason code, see {@code NanSessionListener.FAIL_*}.
+     * @param reason Failure reason code, see
+     *            {@code WifiNanSessionCallback.FAIL_*}.
      */
     public void onConfigFailed(ConfigRequest failedConfig, int reason) {
         Log.w(TAG, "onConfigFailed: called in stub - override if interested or disable");
@@ -136,11 +138,12 @@
 
     /**
      * Called when NAN cluster is down. Event will only be delivered if
-     * registered using {@link WifiNanEventListener#LISTEN_NAN_DOWN}. A dummy (empty
-     * implementation printing out a warning). Make sure to override if
+     * registered using {@link WifiNanEventCallback#LISTEN_NAN_DOWN}. A dummy
+     * (empty implementation printing out a warning). Make sure to override if
      * registered.
      *
-     * @param reason Reason code for event, see {@code NanSessionListener.FAIL_*}.
+     * @param reason Reason code for event, see
+     *            {@code WifiNanSessionCallback.FAIL_*}.
      */
     public void onNanDown(int reason) {
         Log.w(TAG, "onNanDown: called in stub - override if interested or disable");
@@ -152,7 +155,7 @@
      * implication is that peers you've been communicating with may no longer
      * recognize you and you need to re-establish your identity. Event will only
      * be delivered if registered using
-     * {@link WifiNanEventListener#LISTEN_IDENTITY_CHANGED}. A dummy (empty
+     * {@link WifiNanEventCallback#LISTEN_IDENTITY_CHANGED}. A dummy (empty
      * implementation printing out a warning). Make sure to override if
      * registered.
      */
@@ -163,7 +166,7 @@
     /**
      * {@hide}
      */
-    public IWifiNanEventListener callback = new IWifiNanEventListener.Stub() {
+    public IWifiNanEventCallback callback = new IWifiNanEventCallback.Stub() {
         @Override
         public void onConfigCompleted(ConfigRequest completedConfig) {
             if (VDBG) Log.v(TAG, "onConfigCompleted: configRequest=" + completedConfig);
diff --git a/wifi/java/android/net/wifi/nan/WifiNanManager.java b/wifi/java/android/net/wifi/nan/WifiNanManager.java
index 667c4b1..d483bc0 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanManager.java
+++ b/wifi/java/android/net/wifi/nan/WifiNanManager.java
@@ -42,7 +42,7 @@
     private static final boolean VDBG = false; // STOPSHIP if true
 
     private IBinder mBinder;
-
+    private int mClientId = -1;
     private IWifiNanManager mService;
 
     /**
@@ -59,21 +59,25 @@
      * have explicitly {@link WifiNanManager#disconnect()} need to call this
      * function to re-connect.
      *
-     * @param listener A listener extended from {@link WifiNanEventListener}.
-     * @param events The set of events to be delivered to the {@code listener}.
-     *            OR'd event flags from {@link WifiNanEventListener
-     *            NanEventListener.LISTEN*}.
+     * @param callback A callback extended from {@link WifiNanEventCallback}.
+     * @param events The set of events to be delivered to the {@code callback}.
+     *            OR'd event flags from {@link WifiNanEventCallback
+     *            WifiNanEventCallback.LISTEN*}.
      */
-    public void connect(WifiNanEventListener listener, int events) {
+    public void connect(WifiNanEventCallback callback, int events) {
         try {
             if (VDBG) Log.v(TAG, "connect()");
-            if (listener == null) {
-                throw new IllegalArgumentException("Invalid listener - must not be null");
+            if (callback == null) {
+                throw new IllegalArgumentException("Invalid callback - must not be null");
+            }
+            if (mClientId != -1) {
+                Log.w(TAG, "connect(): mClientId=" + mClientId
+                        + ": seems to calling connect() without disconnecting() first!");
             }
             if (mBinder == null) {
                 mBinder = new Binder();
             }
-            mService.connect(mBinder, listener.callback, events);
+            mClientId = mService.connect(mBinder, callback.callback, events);
         } catch (RemoteException e) {
             Log.w(TAG, "connect RemoteException (FYI - ignoring): " + e);
         }
@@ -86,13 +90,14 @@
      * are cancelled.
      * <p>
      * An application may then re-connect using
-     * {@link WifiNanManager#connect(WifiNanEventListener, int)} .
+     * {@link WifiNanManager#connect(WifiNanEventCallback, int)} .
      */
     public void disconnect() {
         try {
             if (VDBG) Log.v(TAG, "disconnect()");
-            mService.disconnect(mBinder);
+            mService.disconnect(mClientId, mBinder);
             mBinder = null;
+            mClientId = -1;
         } catch (RemoteException e) {
             Log.w(TAG, "disconnect RemoteException (FYI - ignoring): " + e);
         }
@@ -105,8 +110,8 @@
      * multiple applications and configure NAN differently from individual
      * requests.
      * <p>
-     * The {@link WifiNanEventListener#onConfigCompleted(ConfigRequest)} will be
-     * called when configuration is completed (if a listener is registered for
+     * The {@link WifiNanEventCallback#onConfigCompleted(ConfigRequest)} will be
+     * called when configuration is completed (if a callback is registered for
      * this specific event).
      *
      * @param configRequest The requested NAN configuration.
@@ -114,7 +119,7 @@
     public void requestConfig(ConfigRequest configRequest) {
         if (VDBG) Log.v(TAG, "requestConfig(): configRequest=" + configRequest);
         try {
-            mService.requestConfig(configRequest);
+            mService.requestConfig(mClientId, configRequest);
         } catch (RemoteException e) {
             Log.w(TAG, "requestConfig RemoteException (FYI - ignoring): " + e);
         }
@@ -122,25 +127,23 @@
 
     /**
      * Request a NAN publish session. The results of the publish session
-     * operation will result in callbacks to the indicated listener:
-     * {@link WifiNanSessionListener NanSessionListener.on*}.
+     * operation will result in callbacks to the indicated callback:
+     * {@link WifiNanSessionCallback NanSessionCallback.on*}.
      *
-     * @param publishData The {@link PublishData} specifying the contents of the
-     *            publish session.
-     * @param publishSettings The {@link PublishSettings} specifying the
-     *            settings for the publish session.
-     * @param listener The {@link WifiNanSessionListener} derived objects to be used
-     *            for the event callbacks specified by {@code events}.
-     * @param events The list of events to be delivered to the {@code listener}
-     *            object. An OR'd value of {@link WifiNanSessionListener
-     *            NanSessionListener.LISTEN_*}.
+     * @param publishConfig The {@link PublishConfig} specifying the
+     *            configuration of the publish session.
+     * @param callback The {@link WifiNanSessionCallback} derived objects to be
+     *            used for the event callbacks specified by {@code events}.
+     * @param events The list of events to be delivered to the {@code callback}
+     *            object. An OR'd value of {@link WifiNanSessionCallback
+     *            WifiNanSessionCallback.LISTEN_*}.
      * @return The {@link WifiNanPublishSession} which can be used to further
      *         control the publish session.
      */
-    public WifiNanPublishSession publish(PublishData publishData, PublishSettings publishSettings,
-            WifiNanSessionListener listener, int events) {
-        return publishRaw(publishData, publishSettings, listener,
-                events | WifiNanSessionListener.LISTEN_HIDDEN_FLAGS);
+    public WifiNanPublishSession publish(PublishConfig publishConfig,
+            WifiNanSessionCallback callback, int events) {
+        return publishRaw(publishConfig, callback,
+                events | WifiNanSessionCallback.LISTEN_HIDDEN_FLAGS);
     }
 
     /**
@@ -148,30 +151,30 @@
      *
      * @hide
      */
-    public WifiNanPublishSession publishRaw(PublishData publishData,
-            PublishSettings publishSettings, WifiNanSessionListener listener, int events) {
-        if (VDBG) Log.v(TAG, "publish(): data='" + publishData + "', settings=" + publishSettings);
+    public WifiNanPublishSession publishRaw(PublishConfig publishConfig,
+            WifiNanSessionCallback callback, int events) {
+        if (VDBG) Log.v(TAG, "publish(): config=" + publishConfig);
 
-        if (publishSettings.mPublishType == PublishSettings.PUBLISH_TYPE_UNSOLICITED
-                && publishData.mRxFilterLength != 0) {
-            throw new IllegalArgumentException("Invalid publish data & settings: UNSOLICITED "
+        if (publishConfig.mPublishType == PublishConfig.PUBLISH_TYPE_UNSOLICITED
+                && publishConfig.mRxFilterLength != 0) {
+            throw new IllegalArgumentException("Invalid publish config: UNSOLICITED "
                     + "publishes (active) can't have an Rx filter");
         }
-        if (publishSettings.mPublishType == PublishSettings.PUBLISH_TYPE_SOLICITED
-                && publishData.mTxFilterLength != 0) {
-            throw new IllegalArgumentException("Invalid publish data & settings: SOLICITED "
+        if (publishConfig.mPublishType == PublishConfig.PUBLISH_TYPE_SOLICITED
+                && publishConfig.mTxFilterLength != 0) {
+            throw new IllegalArgumentException("Invalid publish config: SOLICITED "
                     + "publishes (passive) can't have a Tx filter");
         }
-        if (listener == null) {
-            throw new IllegalArgumentException("Invalid listener - must not be null");
+        if (callback == null) {
+            throw new IllegalArgumentException("Invalid callback - must not be null");
         }
 
         int sessionId;
 
         try {
-            sessionId = mService.createSession(listener.callback, events);
+            sessionId = mService.createSession(mClientId, callback.callback, events);
             if (DBG) Log.d(TAG, "publish: session created - sessionId=" + sessionId);
-            mService.publish(sessionId, publishData, publishSettings);
+            mService.publish(mClientId, sessionId, publishConfig);
         } catch (RemoteException e) {
             Log.w(TAG, "createSession/publish RemoteException: " + e);
             return null;
@@ -183,48 +186,46 @@
     /**
      * {@hide}
      */
-    public void publish(int sessionId, PublishData publishData, PublishSettings publishSettings) {
-        if (VDBG) Log.v(TAG, "publish(): data='" + publishData + "', settings=" + publishSettings);
+    public void publish(int sessionId, PublishConfig publishConfig) {
+        if (VDBG) Log.v(TAG, "publish(): config=" + publishConfig);
 
-        if (publishSettings.mPublishType == PublishSettings.PUBLISH_TYPE_UNSOLICITED
-                && publishData.mRxFilterLength != 0) {
-            throw new IllegalArgumentException("Invalid publish data & settings: UNSOLICITED "
+        if (publishConfig.mPublishType == PublishConfig.PUBLISH_TYPE_UNSOLICITED
+                && publishConfig.mRxFilterLength != 0) {
+            throw new IllegalArgumentException("Invalid publish config: UNSOLICITED "
                     + "publishes (active) can't have an Rx filter");
         }
-        if (publishSettings.mPublishType == PublishSettings.PUBLISH_TYPE_SOLICITED
-                && publishData.mTxFilterLength != 0) {
-            throw new IllegalArgumentException("Invalid publish data & settings: SOLICITED "
+        if (publishConfig.mPublishType == PublishConfig.PUBLISH_TYPE_SOLICITED
+                && publishConfig.mTxFilterLength != 0) {
+            throw new IllegalArgumentException("Invalid publish config: SOLICITED "
                     + "publishes (passive) can't have a Tx filter");
         }
 
         try {
-            mService.publish(sessionId, publishData, publishSettings);
+            mService.publish(mClientId, sessionId, publishConfig);
         } catch (RemoteException e) {
             Log.w(TAG, "publish RemoteException: " + e);
         }
     }
+
     /**
      * Request a NAN subscribe session. The results of the subscribe session
-     * operation will result in callbacks to the indicated listener:
-     * {@link WifiNanSessionListener NanSessionListener.on*}.
+     * operation will result in callbacks to the indicated callback:
+     * {@link WifiNanSessionCallback WifiNanSessionCallback.on*}.
      *
-     * @param subscribeData The {@link SubscribeData} specifying the contents of
-     *            the subscribe session.
-     * @param subscribeSettings The {@link SubscribeSettings} specifying the
-     *            settings for the subscribe session.
-     * @param listener The {@link WifiNanSessionListener} derived objects to be used
-     *            for the event callbacks specified by {@code events}.
-     * @param events The list of events to be delivered to the {@code listener}
-     *            object. An OR'd value of {@link WifiNanSessionListener
-     *            NanSessionListener.LISTEN_*}.
+     * @param subscribeConfig The {@link SubscribeConfig} specifying the
+     *            configuration of the subscribe session.
+     * @param callback The {@link WifiNanSessionCallback} derived objects to be
+     *            used for the event callbacks specified by {@code events}.
+     * @param events The list of events to be delivered to the {@code callback}
+     *            object. An OR'd value of {@link WifiNanSessionCallback
+     *            WifiNanSessionCallback.LISTEN_*}.
      * @return The {@link WifiNanSubscribeSession} which can be used to further
      *         control the subscribe session.
      */
-    public WifiNanSubscribeSession subscribe(SubscribeData subscribeData,
-            SubscribeSettings subscribeSettings,
-            WifiNanSessionListener listener, int events) {
-        return subscribeRaw(subscribeData, subscribeSettings, listener,
-                events | WifiNanSessionListener.LISTEN_HIDDEN_FLAGS);
+    public WifiNanSubscribeSession subscribe(SubscribeConfig subscribeConfig,
+            WifiNanSessionCallback callback, int events) {
+        return subscribeRaw(subscribeConfig, callback,
+                events | WifiNanSessionCallback.LISTEN_HIDDEN_FLAGS);
     }
 
     /**
@@ -232,29 +233,29 @@
      *
      * @hide
      */
-    public WifiNanSubscribeSession subscribeRaw(SubscribeData subscribeData,
-            SubscribeSettings subscribeSettings, WifiNanSessionListener listener, int events) {
+    public WifiNanSubscribeSession subscribeRaw(SubscribeConfig subscribeConfig,
+            WifiNanSessionCallback callback, int events) {
         if (VDBG) {
-            Log.v(TAG, "subscribe(): data='" + subscribeData + "', settings=" + subscribeSettings);
+            Log.v(TAG, "subscribe(): config=" + subscribeConfig);
         }
 
-        if (subscribeSettings.mSubscribeType == SubscribeSettings.SUBSCRIBE_TYPE_ACTIVE
-                && subscribeData.mRxFilterLength != 0) {
+        if (subscribeConfig.mSubscribeType == SubscribeConfig.SUBSCRIBE_TYPE_ACTIVE
+                && subscribeConfig.mRxFilterLength != 0) {
             throw new IllegalArgumentException(
-                    "Invalid subscribe data & settings: ACTIVE subscribes can't have an Rx filter");
+                    "Invalid subscribe config: ACTIVE subscribes can't have an Rx filter");
         }
-        if (subscribeSettings.mSubscribeType == SubscribeSettings.SUBSCRIBE_TYPE_PASSIVE
-                && subscribeData.mTxFilterLength != 0) {
+        if (subscribeConfig.mSubscribeType == SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE
+                && subscribeConfig.mTxFilterLength != 0) {
             throw new IllegalArgumentException(
-                    "Invalid subscribe data & settings: PASSIVE subscribes can't have a Tx filter");
+                    "Invalid subscribe config: PASSIVE subscribes can't have a Tx filter");
         }
 
         int sessionId;
 
         try {
-            sessionId = mService.createSession(listener.callback, events);
+            sessionId = mService.createSession(mClientId, callback.callback, events);
             if (DBG) Log.d(TAG, "subscribe: session created - sessionId=" + sessionId);
-            mService.subscribe(sessionId, subscribeData, subscribeSettings);
+            mService.subscribe(mClientId, sessionId, subscribeConfig);
         } catch (RemoteException e) {
             Log.w(TAG, "createSession/subscribe RemoteException: " + e);
             return null;
@@ -266,25 +267,24 @@
     /**
      * {@hide}
      */
-    public void subscribe(int sessionId, SubscribeData subscribeData,
-            SubscribeSettings subscribeSettings) {
+    public void subscribe(int sessionId, SubscribeConfig subscribeConfig) {
         if (VDBG) {
-            Log.v(TAG, "subscribe(): data='" + subscribeData + "', settings=" + subscribeSettings);
+            Log.v(TAG, "subscribe(): config=" + subscribeConfig);
         }
 
-        if (subscribeSettings.mSubscribeType == SubscribeSettings.SUBSCRIBE_TYPE_ACTIVE
-                && subscribeData.mRxFilterLength != 0) {
+        if (subscribeConfig.mSubscribeType == SubscribeConfig.SUBSCRIBE_TYPE_ACTIVE
+                && subscribeConfig.mRxFilterLength != 0) {
             throw new IllegalArgumentException(
-                    "Invalid subscribe data & settings: ACTIVE subscribes can't have an Rx filter");
+                    "Invalid subscribe config: ACTIVE subscribes can't have an Rx filter");
         }
-        if (subscribeSettings.mSubscribeType == SubscribeSettings.SUBSCRIBE_TYPE_PASSIVE
-                && subscribeData.mTxFilterLength != 0) {
+        if (subscribeConfig.mSubscribeType == SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE
+                && subscribeConfig.mTxFilterLength != 0) {
             throw new IllegalArgumentException(
-                    "Invalid subscribe data & settings: PASSIVE subscribes can't have a Tx filter");
+                    "Invalid subscribe config: PASSIVE subscribes can't have a Tx filter");
         }
 
         try {
-            mService.subscribe(sessionId, subscribeData, subscribeSettings);
+            mService.subscribe(mClientId, sessionId, subscribeConfig);
         } catch (RemoteException e) {
             Log.w(TAG, "subscribe RemoteException: " + e);
         }
@@ -297,7 +297,7 @@
         if (DBG) Log.d(TAG, "Stop NAN session #" + sessionId);
 
         try {
-            mService.stopSession(sessionId);
+            mService.stopSession(mClientId, sessionId);
         } catch (RemoteException e) {
             Log.w(TAG, "stopSession RemoteException (FYI - ignoring): " + e);
         }
@@ -310,7 +310,7 @@
         if (DBG) Log.d(TAG, "Destroy NAN session #" + sessionId);
 
         try {
-            mService.destroySession(sessionId);
+            mService.destroySession(mClientId, sessionId);
         } catch (RemoteException e) {
             Log.w(TAG, "destroySession RemoteException (FYI - ignoring): " + e);
         }
@@ -326,7 +326,7 @@
                 Log.v(TAG, "sendMessage(): sessionId=" + sessionId + ", peerId=" + peerId
                         + ", messageLength=" + messageLength + ", messageId=" + messageId);
             }
-            mService.sendMessage(sessionId, peerId, message, messageLength, messageId);
+            mService.sendMessage(mClientId, sessionId, peerId, message, messageLength, messageId);
         } catch (RemoteException e) {
             Log.w(TAG, "subscribe RemoteException (FYI - ignoring): " + e);
         }
diff --git a/wifi/java/android/net/wifi/nan/WifiNanPublishSession.java b/wifi/java/android/net/wifi/nan/WifiNanPublishSession.java
index 81b38f4..eae9c65 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanPublishSession.java
+++ b/wifi/java/android/net/wifi/nan/WifiNanPublishSession.java
@@ -18,8 +18,8 @@
 
 /**
  * A representation of a NAN publish session. Created when
- * {@link WifiNanManager#publish(PublishData, PublishSettings, WifiNanSessionListener, int)}
- * is executed. The object can be used to stop and re-start (re-configure) the
+ * {@link WifiNanManager#publish(PublishConfig, WifiNanSessionListener, int)} is
+ * executed. The object can be used to stop and re-start (re-configure) the
  * publish session.
  *
  * @hide PROPOSED_NAN_API
@@ -34,14 +34,13 @@
 
     /**
      * Restart/re-configure the publish session. Note that the
-     * {@link WifiNanSessionListener} is not replaced - the same listener used at
-     * creation is still used.
+     * {@link WifiNanSessionListener} is not replaced - the same listener used
+     * at creation is still used.
      *
-     * @param publishData The data ({@link PublishData}) to publish.
-     * @param publishSettings The settings ({@link PublishSettings}) of the
+     * @param publishConfig The configuration ({@link PublishConfig}) of the
      *            publish session.
      */
-    public void publish(PublishData publishData, PublishSettings publishSettings) {
-        mManager.publish(mSessionId, publishData, publishSettings);
+    public void publish(PublishConfig publishConfig) {
+        mManager.publish(mSessionId, publishConfig);
     }
 }
diff --git a/wifi/java/android/net/wifi/nan/WifiNanSession.java b/wifi/java/android/net/wifi/nan/WifiNanSession.java
index bc1787f..a903583 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanSession.java
+++ b/wifi/java/android/net/wifi/nan/WifiNanSession.java
@@ -94,11 +94,11 @@
      * Sends a message to the specified destination. Message transmission is
      * part of the current discovery session - i.e. executed subsequent to a
      * publish/subscribe
-     * {@link WifiNanSessionListener#onMatch(int, byte[], int, byte[], int)}
+     * {@link WifiNanSessionCallback#onMatch(int, byte[], int, byte[], int)}
      * event.
      *
      * @param peerId The peer's ID for the message. Must be a result of an
-     *            {@link WifiNanSessionListener#onMatch(int, byte[], int, byte[], int)}
+     *            {@link WifiNanSessionCallback#onMatch(int, byte[], int, byte[], int)}
      *            event.
      * @param message The message to be transmitted.
      * @param messageLength The number of bytes from the {@code message} to be
diff --git a/wifi/java/android/net/wifi/nan/WifiNanSessionListener.java b/wifi/java/android/net/wifi/nan/WifiNanSessionCallback.java
similarity index 76%
rename from wifi/java/android/net/wifi/nan/WifiNanSessionListener.java
rename to wifi/java/android/net/wifi/nan/WifiNanSessionCallback.java
index b9af7def..884fcf5 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanSessionListener.java
+++ b/wifi/java/android/net/wifi/nan/WifiNanSessionCallback.java
@@ -26,29 +26,29 @@
  * Base class for NAN session events callbacks. Should be extended by
  * applications wanting notifications. The callbacks are registered when a
  * publish or subscribe session is created using
- * {@link WifiNanManager#publish(PublishData, PublishSettings, WifiNanSessionListener, int)}
- * or
- * {@link WifiNanManager#subscribe(SubscribeData, SubscribeSettings, WifiNanSessionListener, int)}
+ * {@link WifiNanManager#publish(PublishConfig, WifiNanSessionCallback, int)} or
+ * {@link WifiNanManager#subscribe(SubscribeConfig, WifiNanSessionCallback, int)}
  * . These are callbacks applying to a specific NAN session. Events
- * corresponding to the NAN link are delivered using {@link WifiNanEventListener}.
+ * corresponding to the NAN link are delivered using
+ * {@link WifiNanEventCallback}.
  * <p>
- * A single listener is registered at session creation - it cannot be replaced.
+ * A single callback is registered at session creation - it cannot be replaced.
  * <p>
  * During registration specify which specific events are desired using a set of
- * {@code NanSessionListener.LISTEN_*} flags OR'd together. Only those events
- * will be delivered to the registered listener. Override those callbacks
- * {@code NanSessionListener.on*} for the registered events.
+ * {@code WifiNanSessionCallback.LISTEN_*} flags OR'd together. Only those
+ * events will be delivered to the registered callback. Override those callbacks
+ * {@code WifiNanSessionCallback.on*} for the registered events.
  *
  * @hide PROPOSED_NAN_API
  */
-public class WifiNanSessionListener {
-    private static final String TAG = "WifiNanSessionListener";
+public class WifiNanSessionCallback {
+    private static final String TAG = "WifiNanSessionCallback";
     private static final boolean DBG = false;
     private static final boolean VDBG = false; // STOPSHIP if true
 
     /**
      * Publish fail callback event registration flag. Corresponding callback is
-     * {@link WifiNanSessionListener#onPublishFail(int)}.
+     * {@link WifiNanSessionCallback#onPublishFail(int)}.
      *
      * @hide
      */
@@ -56,13 +56,13 @@
 
     /**
      * Publish terminated callback event registration flag. Corresponding
-     * callback is {@link WifiNanSessionListener#onPublishTerminated(int)}.
+     * callback is {@link WifiNanSessionCallback#onPublishTerminated(int)}.
      */
     public static final int LISTEN_PUBLISH_TERMINATED = 0x1 << 1;
 
     /**
      * Subscribe fail callback event registration flag. Corresponding callback
-     * is {@link WifiNanSessionListener#onSubscribeFail(int)}.
+     * is {@link WifiNanSessionCallback#onSubscribeFail(int)}.
      *
      * @hide
      */
@@ -70,14 +70,14 @@
 
     /**
      * Subscribe terminated callback event registration flag. Corresponding
-     * callback is {@link WifiNanSessionListener#onSubscribeTerminated(int)}.
+     * callback is {@link WifiNanSessionCallback#onSubscribeTerminated(int)}.
      */
     public static final int LISTEN_SUBSCRIBE_TERMINATED = 0x1 << 3;
 
     /**
      * Match (discovery: publish or subscribe) callback event registration flag.
      * Corresponding callback is
-     * {@link WifiNanSessionListener#onMatch(int, byte[], int, byte[], int)}.
+     * {@link WifiNanSessionCallback#onMatch(int, byte[], int, byte[], int)}.
      *
      * @hide
      */
@@ -85,7 +85,7 @@
 
     /**
      * Message sent successfully callback event registration flag. Corresponding
-     * callback is {@link WifiNanSessionListener#onMessageSendSuccess()}.
+     * callback is {@link WifiNanSessionCallback#onMessageSendSuccess()}.
      *
      * @hide
      */
@@ -93,7 +93,7 @@
 
     /**
      * Message sending failure callback event registration flag. Corresponding
-     * callback is {@link WifiNanSessionListener#onMessageSendFail(int)}.
+     * callback is {@link WifiNanSessionCallback#onMessageSendFail(int)}.
      *
      * @hide
      */
@@ -101,7 +101,7 @@
 
     /**
      * Message received callback event registration flag. Corresponding callback
-     * is {@link WifiNanSessionListener#onMessageReceived(int, byte[], int)}.
+     * is {@link WifiNanSessionCallback#onMessageReceived(int, byte[], int)}.
      *
      * @hide
      */
@@ -118,47 +118,47 @@
             | LISTEN_MESSAGE_RECEIVED;
 
     /**
-     * Failure reason flag for {@link WifiNanEventListener} and
-     * {@link WifiNanSessionListener} callbacks. Indicates no resources to execute
-     * the requested operation.
+     * Failure reason flag for {@link WifiNanEventCallback} and
+     * {@link WifiNanSessionCallback} callbacks. Indicates no resources to
+     * execute the requested operation.
      */
     public static final int FAIL_REASON_NO_RESOURCES = 0;
 
     /**
-     * Failure reason flag for {@link WifiNanEventListener} and
-     * {@link WifiNanSessionListener} callbacks. Indicates invalid argument in the
-     * requested operation.
+     * Failure reason flag for {@link WifiNanEventCallback} and
+     * {@link WifiNanSessionCallback} callbacks. Indicates invalid argument in
+     * the requested operation.
      */
     public static final int FAIL_REASON_INVALID_ARGS = 1;
 
     /**
-     * Failure reason flag for {@link WifiNanEventListener} and
-     * {@link WifiNanSessionListener} callbacks. Indicates a message is transmitted
-     * without a match (i.e. a discovery) occurring first.
+     * Failure reason flag for {@link WifiNanEventCallback} and
+     * {@link WifiNanSessionCallback} callbacks. Indicates a message is
+     * transmitted without a match (i.e. a discovery) occurring first.
      */
     public static final int FAIL_REASON_NO_MATCH_SESSION = 2;
 
     /**
-     * Failure reason flag for {@link WifiNanEventListener} and
-     * {@link WifiNanSessionListener} callbacks. Indicates an unspecified error
+     * Failure reason flag for {@link WifiNanEventCallback} and
+     * {@link WifiNanSessionCallback} callbacks. Indicates an unspecified error
      * occurred during the operation.
      */
     public static final int FAIL_REASON_OTHER = 3;
 
     /**
      * Failure reason flag for
-     * {@link WifiNanSessionListener#onPublishTerminated(int)} and
-     * {@link WifiNanSessionListener#onSubscribeTerminated(int)} callbacks.
+     * {@link WifiNanSessionCallback#onPublishTerminated(int)} and
+     * {@link WifiNanSessionCallback#onSubscribeTerminated(int)} callbacks.
      * Indicates that publish or subscribe session is done - i.e. all the
-     * requested operations (per {@link PublishSettings} or
-     * {@link SubscribeSettings}) have been executed.
+     * requested operations (per {@link PublishConfig} or
+     * {@link SubscribeConfig}) have been executed.
      */
     public static final int TERMINATE_REASON_DONE = 0;
 
     /**
      * Failure reason flag for
-     * {@link WifiNanSessionListener#onPublishTerminated(int)} and
-     * {@link WifiNanSessionListener#onSubscribeTerminated(int)} callbacks.
+     * {@link WifiNanSessionCallback#onPublishTerminated(int)} and
+     * {@link WifiNanSessionCallback#onSubscribeTerminated(int)} callbacks.
      * Indicates that publish or subscribe session is terminated due to a
      * failure.
      */
@@ -171,20 +171,21 @@
     private final Handler mHandler;
 
     /**
-     * Constructs a {@link WifiNanSessionListener} using the looper of the current
-     * thread. I.e. all callbacks will be delivered on the current thread.
+     * Constructs a {@link WifiNanSessionCallback} using the looper of the
+     * current thread. I.e. all callbacks will be delivered on the current
+     * thread.
      */
-    public WifiNanSessionListener() {
+    public WifiNanSessionCallback() {
         this(Looper.myLooper());
     }
 
     /**
-     * Constructs a {@link WifiNanSessionListener} using the specified looper. I.e.
-     * all callbacks will delivered on the thread of the specified looper.
+     * Constructs a {@link WifiNanSessionCallback} using the specified looper.
+     * I.e. all callbacks will delivered on the thread of the specified looper.
      *
      * @param looper The looper on which to execute the callbacks.
      */
-    public WifiNanSessionListener(Looper looper) {
+    public WifiNanSessionCallback(Looper looper) {
         if (VDBG) Log.v(TAG, "ctor: looper=" + looper);
         mHandler = new Handler(looper) {
             @Override
@@ -192,31 +193,31 @@
                 if (DBG) Log.d(TAG, "What=" + msg.what + ", msg=" + msg);
                 switch (msg.what) {
                     case LISTEN_PUBLISH_FAIL:
-                        WifiNanSessionListener.this.onPublishFail(msg.arg1);
+                        WifiNanSessionCallback.this.onPublishFail(msg.arg1);
                         break;
                     case LISTEN_PUBLISH_TERMINATED:
-                        WifiNanSessionListener.this.onPublishTerminated(msg.arg1);
+                        WifiNanSessionCallback.this.onPublishTerminated(msg.arg1);
                         break;
                     case LISTEN_SUBSCRIBE_FAIL:
-                        WifiNanSessionListener.this.onSubscribeFail(msg.arg1);
+                        WifiNanSessionCallback.this.onSubscribeFail(msg.arg1);
                         break;
                     case LISTEN_SUBSCRIBE_TERMINATED:
-                        WifiNanSessionListener.this.onSubscribeTerminated(msg.arg1);
+                        WifiNanSessionCallback.this.onSubscribeTerminated(msg.arg1);
                         break;
                     case LISTEN_MATCH:
-                        WifiNanSessionListener.this.onMatch(
+                        WifiNanSessionCallback.this.onMatch(
                                 msg.getData().getInt(MESSAGE_BUNDLE_KEY_PEER_ID),
                                 msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE), msg.arg1,
                                 msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE2), msg.arg2);
                         break;
                     case LISTEN_MESSAGE_SEND_SUCCESS:
-                        WifiNanSessionListener.this.onMessageSendSuccess(msg.arg1);
+                        WifiNanSessionCallback.this.onMessageSendSuccess(msg.arg1);
                         break;
                     case LISTEN_MESSAGE_SEND_FAIL:
-                        WifiNanSessionListener.this.onMessageSendFail(msg.arg1, msg.arg2);
+                        WifiNanSessionCallback.this.onMessageSendFail(msg.arg1, msg.arg2);
                         break;
                     case LISTEN_MESSAGE_RECEIVED:
-                        WifiNanSessionListener.this.onMessageReceived(msg.arg2,
+                        WifiNanSessionCallback.this.onMessageReceived(msg.arg2,
                                 msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE), msg.arg1);
                         break;
                 }
@@ -229,8 +230,8 @@
      * implementation printing out a log message). Override to implement your
      * custom response.
      *
-     * @param reason The failure reason using {@code NanSessionListener.FAIL_*}
-     *            codes.
+     * @param reason The failure reason using
+     *            {@code WifiNanSessionCallback.FAIL_*} codes.
      */
     public void onPublishFail(int reason) {
         if (VDBG) Log.v(TAG, "onPublishFail: called in stub - override if interested");
@@ -238,12 +239,13 @@
 
     /**
      * Called when a publish operation terminates. Event will only be delivered
-     * if registered using {@link WifiNanSessionListener#LISTEN_PUBLISH_TERMINATED}.
-     * A dummy (empty implementation printing out a warning). Make sure to
-     * override if registered.
+     * if registered using
+     * {@link WifiNanSessionCallback#LISTEN_PUBLISH_TERMINATED}. A dummy (empty
+     * implementation printing out a warning). Make sure to override if
+     * registered.
      *
      * @param reason The termination reason using
-     *            {@code NanSessionListener.TERMINATE_*} codes.
+     *            {@code WifiNanSessionCallback.TERMINATE_*} codes.
      */
     public void onPublishTerminated(int reason) {
         Log.w(TAG, "onPublishTerminated: called in stub - override if interested or disable");
@@ -254,8 +256,8 @@
      * implementation printing out a log message). Override to implement your
      * custom response.
      *
-     * @param reason The failure reason using {@code NanSessionListener.FAIL_*}
-     *            codes.
+     * @param reason The failure reason using
+     *            {@code WifiNanSessionCallback.FAIL_*} codes.
      */
     public void onSubscribeFail(int reason) {
         if (VDBG) Log.v(TAG, "onSubscribeFail: called in stub - override if interested");
@@ -264,12 +266,12 @@
     /**
      * Called when a subscribe operation terminates. Event will only be
      * delivered if registered using
-     * {@link WifiNanSessionListener#LISTEN_SUBSCRIBE_TERMINATED}. A dummy (empty
-     * implementation printing out a warning). Make sure to override if
+     * {@link WifiNanSessionCallback#LISTEN_SUBSCRIBE_TERMINATED}. A dummy
+     * (empty implementation printing out a warning). Make sure to override if
      * registered.
      *
      * @param reason The termination reason using
-     *            {@code NanSessionListener.TERMINATE_*} codes.
+     *            {@code WifiNanSessionCallback.TERMINATE_*} codes.
      */
     public void onSubscribeTerminated(int reason) {
         Log.w(TAG, "onSubscribeTerminated: called in stub - override if interested or disable");
@@ -303,7 +305,7 @@
      * message). Override to implement your custom response.
      * <p>
      * Note that either this callback or
-     * {@link WifiNanSessionListener#onMessageSendFail(int, int)} will be
+     * {@link WifiNanSessionCallback#onMessageSendFail(int, int)} will be
      * received - never both.
      */
     public void onMessageSendSuccess(int messageId) {
@@ -319,11 +321,11 @@
      * message). Override to implement your custom response.
      * <p>
      * Note that either this callback or
-     * {@link WifiNanSessionListener#onMessageSendSuccess(int)} will be received
+     * {@link WifiNanSessionCallback#onMessageSendSuccess(int)} will be received
      * - never both
      *
-     * @param reason The failure reason using {@code NanSessionListener.FAIL_*}
-     *            codes.
+     * @param reason The failure reason using
+     *            {@code WifiNanSessionCallback.FAIL_*} codes.
      */
     public void onMessageSendFail(int messageId, int reason) {
         if (VDBG) Log.v(TAG, "onMessageSendFail: called in stub - override if interested");
@@ -346,7 +348,7 @@
     /**
      * {@hide}
      */
-    public IWifiNanSessionListener callback = new IWifiNanSessionListener.Stub() {
+    public IWifiNanSessionCallback callback = new IWifiNanSessionCallback.Stub() {
         @Override
         public void onPublishFail(int reason) {
             if (VDBG) Log.v(TAG, "onPublishFail: reason=" + reason);
diff --git a/wifi/java/android/net/wifi/nan/WifiNanSubscribeSession.java b/wifi/java/android/net/wifi/nan/WifiNanSubscribeSession.java
index 7dfdd32..d2f13c8 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanSubscribeSession.java
+++ b/wifi/java/android/net/wifi/nan/WifiNanSubscribeSession.java
@@ -18,7 +18,7 @@
 
 /**
  * A representation of a NAN subscribe session. Created when
- * {@link WifiNanManager#subscribe(SubscribeData, SubscribeSettings, WifiNanSessionListener, int)}
+ * {@link WifiNanManager#subscribe(SubscribeConfig, WifiNanSessionListener, int)}
  * is executed. The object can be used to stop and re-start (re-configure) the
  * subscribe session.
  *
@@ -34,14 +34,13 @@
 
     /**
      * Restart/re-configure the subscribe session. Note that the
-     * {@link WifiNanSessionListener} is not replaced - the same listener used at
-     * creation is still used.
+     * {@link WifiNanSessionListener} is not replaced - the same listener used
+     * at creation is still used.
      *
-     * @param subscribeData The data ({@link SubscribeData}) to subscribe.
-     * @param subscribeSettings The settings ({@link SubscribeSettings}) of the
+     * @param subscribeConfig The configuration ({@link SubscribeConfig}) of the
      *            subscribe session.
      */
-    public void subscribe(SubscribeData subscribeData, SubscribeSettings subscribeSettings) {
-        mManager.subscribe(mSessionId, subscribeData, subscribeSettings);
+    public void subscribe(SubscribeConfig subscribeConfig) {
+        mManager.subscribe(mSessionId, subscribeConfig);
     }
 }