diff --git a/core/java/android/net/nsd/INsdManager.aidl b/core/java/android/net/nsd/INsdManager.aidl
index 077a675..3361a7b 100644
--- a/core/java/android/net/nsd/INsdManager.aidl
+++ b/core/java/android/net/nsd/INsdManager.aidl
@@ -26,4 +26,5 @@
 interface INsdManager
 {
     Messenger getMessenger();
+    void setEnabled(boolean enable);
 }
diff --git a/core/java/android/net/nsd/NsdManager.java b/core/java/android/net/nsd/NsdManager.java
index dac8d20..77e97e1 100644
--- a/core/java/android/net/nsd/NsdManager.java
+++ b/core/java/android/net/nsd/NsdManager.java
@@ -16,6 +16,8 @@
 
 package android.net.nsd;
 
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
 import android.content.Context;
 import android.os.Binder;
 import android.os.IBinder;
@@ -133,6 +135,40 @@
     private static final String TAG = "NsdManager";
     INsdManager mService;
 
+    /**
+     * Broadcast intent action to indicate whether network service discovery is
+     * enabled or disabled. An extra {@link #EXTRA_NSD_STATE} provides the state
+     * information as int.
+     *
+     * @see #EXTRA_NSD_STATE
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_NSD_STATE_CHANGED =
+        "android.net.nsd.STATE_CHANGED";
+
+    /**
+     * The lookup key for an int that indicates whether network service discovery is enabled
+     * or disabled. Retrieve it with {@link android.content.Intent#getIntExtra(String,int)}.
+     *
+     * @see #NSD_STATE_DISABLED
+     * @see #NSD_STATE_ENABLED
+     */
+    public static final String EXTRA_NSD_STATE = "nsd_state";
+
+    /**
+     * Network service discovery is disabled
+     *
+     * @see #ACTION_NSD_STATE_CHANGED
+     */
+    public static final int NSD_STATE_DISABLED = 1;
+
+    /**
+     * Network service discovery is enabled
+     *
+     * @see #ACTION_NSD_STATE_CHANGED
+     */
+    public static final int NSD_STATE_ENABLED = 2;
+
     private static final int BASE = Protocol.BASE_NSD_MANAGER;
 
     /** @hide */
@@ -188,6 +224,12 @@
     /** @hide */
     public static final int STOP_RESOLVE_SUCCEEDED                  = BASE + 23;
 
+    /** @hide */
+    public static final int ENABLE                                  = BASE + 24;
+    /** @hide */
+    public static final int DISABLE                                 = BASE + 25;
+
+
     /**
      * Create a new Nsd instance. Applications use
      * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
@@ -312,8 +354,8 @@
         private DnsSdResolveListener mDnsSdResolveListener;
         private ActionListener mDnsSdStopResolveListener;
 
-        AsyncChannel mAsyncChannel;
-        ServiceHandler mHandler;
+        private AsyncChannel mAsyncChannel;
+        private ServiceHandler mHandler;
         class ServiceHandler extends Handler {
             ServiceHandler(Looper looper) {
                 super(looper);
@@ -594,6 +636,13 @@
         c.mAsyncChannel.sendMessage(STOP_RESOLVE);
     }
 
+    /** Internal use only @hide */
+    public void setEnabled(boolean enabled) {
+        try {
+            mService.setEnabled(enabled);
+        } catch (RemoteException e) { }
+    }
+
     /**
      * Get a reference to NetworkService handler. This is used to establish
      * an AsyncChannel communication with the service
diff --git a/services/java/com/android/server/NsdService.java b/services/java/com/android/server/NsdService.java
index 8014e27..f33bf8b 100644
--- a/services/java/com/android/server/NsdService.java
+++ b/services/java/com/android/server/NsdService.java
@@ -17,6 +17,8 @@
 package com.android.server;
 
 import android.content.Context;
+import android.content.ContentResolver;
+import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.net.nsd.DnsSdServiceInfo;
 import android.net.nsd.DnsSdTxtRecord;
@@ -28,6 +30,7 @@
 import android.os.Message;
 import android.os.Messenger;
 import android.os.IBinder;
+import android.provider.Settings;
 import android.util.Slog;
 
 import java.io.FileDescriptor;
@@ -41,6 +44,9 @@
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.util.AsyncChannel;
+import com.android.internal.util.Protocol;
+import com.android.internal.util.State;
+import com.android.internal.util.StateMachine;
 import com.android.server.am.BatteryStatsService;
 import com.android.server.NativeDaemonConnector.Command;
 import com.android.internal.R;
@@ -58,6 +64,8 @@
     private static final boolean DBG = true;
 
     private Context mContext;
+    private ContentResolver mContentResolver;
+    private NsdStateMachine mNsdStateMachine;
 
     /**
      * Clients receiving asynchronous messages
@@ -69,189 +77,342 @@
     private int INVALID_ID = 0;
     private int mUniqueId = 1;
 
-    /**
-     * Handles client(app) connections
-     */
-    private class AsyncServiceHandler extends Handler {
+    private static final int BASE = Protocol.BASE_NSD_MANAGER;
+    private static final int CMD_TO_STRING_COUNT = NsdManager.STOP_RESOLVE - BASE + 1;
+    private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT];
 
-        AsyncServiceHandler(android.os.Looper looper) {
-            super(looper);
-        }
+    static {
+        sCmdToString[NsdManager.DISCOVER_SERVICES - BASE] = "DISCOVER";
+        sCmdToString[NsdManager.STOP_DISCOVERY - BASE] = "STOP-DISCOVER";
+        sCmdToString[NsdManager.REGISTER_SERVICE - BASE] = "REGISTER";
+        sCmdToString[NsdManager.UNREGISTER_SERVICE - BASE] = "UNREGISTER";
+        sCmdToString[NsdManager.RESOLVE_SERVICE - BASE] = "RESOLVE";
+        sCmdToString[NsdManager.STOP_RESOLVE - BASE] = "STOP-RESOLVE";
+    }
 
-        @Override
-        public void handleMessage(Message msg) {
-            ClientInfo clientInfo;
-            DnsSdServiceInfo servInfo;
-            switch (msg.what) {
-                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
-                    if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
-                        AsyncChannel c = (AsyncChannel) msg.obj;
-                        if (DBG) Slog.d(TAG, "New client listening to asynchronous messages");
-                        c.sendMessage(AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED);
-                        ClientInfo cInfo = new ClientInfo(c, msg.replyTo);
-                        if (mClients.size() == 0) {
-                            startMDnsDaemon();
-                        }
-                        mClients.put(msg.replyTo, cInfo);
-                    } else {
-                        Slog.e(TAG, "Client connection failure, error=" + msg.arg1);
-                    }
-                    break;
-                case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
-                    if (msg.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) {
-                        Slog.e(TAG, "Send failed, client connection lost");
-                    } else {
-                        if (DBG) Slog.d(TAG, "Client connection lost with reason: " + msg.arg1);
-                    }
-                    mClients.remove(msg.replyTo);
-                    if (mClients.size() == 0) {
-                        stopMDnsDaemon();
-                    }
-                    break;
-                case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
-                    AsyncChannel ac = new AsyncChannel();
-                    ac.connect(mContext, this, msg.replyTo);
-                    break;
-                case NsdManager.DISCOVER_SERVICES:
-                    if (DBG) Slog.d(TAG, "Discover services");
-                    servInfo = (DnsSdServiceInfo) msg.obj;
-                    clientInfo = mClients.get(msg.replyTo);
-                    if (clientInfo.mDiscoveryId != INVALID_ID) {
-                        //discovery already in progress
-                        if (DBG) Slog.d(TAG, "discovery in progress");
-                        mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
-                                NsdManager.ALREADY_ACTIVE);
-                        break;
-                    }
-                    clientInfo.mDiscoveryId = getUniqueId();
-                    if (discoverServices(clientInfo.mDiscoveryId, servInfo.getServiceType())) {
-                        mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_STARTED);
-                    } else {
-                        mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
-                                NsdManager.ERROR);
-                        clientInfo.mDiscoveryId = INVALID_ID;
-                    }
-                    break;
-                case NsdManager.STOP_DISCOVERY:
-                    if (DBG) Slog.d(TAG, "Stop service discovery");
-                    clientInfo = mClients.get(msg.replyTo);
-                    if (clientInfo.mDiscoveryId == INVALID_ID) {
-                        //already stopped
-                        if (DBG) Slog.d(TAG, "discovery already stopped");
-                        mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
-                                NsdManager.ALREADY_ACTIVE);
-                        break;
-                    }
-                    if (stopServiceDiscovery(clientInfo.mDiscoveryId)) {
-                        clientInfo.mDiscoveryId = INVALID_ID;
-                        mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_SUCCEEDED);
-                    } else {
-                        mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
-                                NsdManager.ERROR);
-                    }
-                    break;
-                case NsdManager.REGISTER_SERVICE:
-                    if (DBG) Slog.d(TAG, "Register service");
-                    clientInfo = mClients.get(msg.replyTo);
-                    if (clientInfo.mRegisteredIds.size() >= ClientInfo.MAX_REG) {
-                        if (DBG) Slog.d(TAG, "register service exceeds limit");
-                        mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
-                                NsdManager.MAX_REGS_REACHED);
-                    }
-
-                    int id = getUniqueId();
-                    if (registerService(id, (DnsSdServiceInfo) msg.obj)) {
-                        clientInfo.mRegisteredIds.add(id);
-                    } else {
-                        mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
-                                NsdManager.ERROR);
-                    }
-                    break;
-                case NsdManager.UNREGISTER_SERVICE:
-                    if (DBG) Slog.d(TAG, "unregister service");
-                    clientInfo = mClients.get(msg.replyTo);
-                    int regId = msg.arg1;
-                    if (clientInfo.mRegisteredIds.remove(new Integer(regId)) &&
-                            unregisterService(regId)) {
-                        mReplyChannel.replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_SUCCEEDED);
-                    } else {
-                        mReplyChannel.replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
-                                NsdManager.ERROR);
-                    }
-                    break;
-                case NsdManager.UPDATE_SERVICE:
-                    if (DBG) Slog.d(TAG, "Update service");
-                    //TODO: implement
-                    mReplyChannel.replyToMessage(msg, NsdManager.UPDATE_SERVICE_FAILED);
-                    break;
-                case NsdManager.RESOLVE_SERVICE:
-                    if (DBG) Slog.d(TAG, "Resolve service");
-                    servInfo = (DnsSdServiceInfo) msg.obj;
-                    clientInfo = mClients.get(msg.replyTo);
-                    if (clientInfo.mResolveId != INVALID_ID) {
-                        //first cancel existing resolve
-                        stopResolveService(clientInfo.mResolveId);
-                    }
-
-                    clientInfo.mResolveId = getUniqueId();
-                    if (!resolveService(clientInfo.mResolveId, servInfo)) {
-                        mReplyChannel.replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
-                                NsdManager.ERROR);
-                        clientInfo.mResolveId = INVALID_ID;
-                    }
-                    break;
-                case NsdManager.STOP_RESOLVE:
-                    if (DBG) Slog.d(TAG, "Stop resolve");
-                    clientInfo = mClients.get(msg.replyTo);
-                    if (clientInfo.mResolveId == INVALID_ID) {
-                        //already stopped
-                        if (DBG) Slog.d(TAG, "resolve already stopped");
-                        mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
-                                NsdManager.ALREADY_ACTIVE);
-                        break;
-                    }
-                    if (stopResolveService(clientInfo.mResolveId)) {
-                        clientInfo.mResolveId = INVALID_ID;
-                        mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_SUCCEEDED);
-                    } else {
-                        mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
-                                NsdManager.ERROR);
-                    }
-                    break;
-                default:
-                    Slog.d(TAG, "NsdServicehandler.handleMessage ignoring msg=" + msg);
-                    break;
-            }
+    private static String cmdToString(int cmd) {
+        cmd -= BASE;
+        if ((cmd >= 0) && (cmd < sCmdToString.length)) {
+            return sCmdToString[cmd];
+        } else {
+            return null;
         }
     }
-    private AsyncServiceHandler mAsyncServiceHandler;
+
+    private class NsdStateMachine extends StateMachine {
+
+        private DefaultState mDefaultState = new DefaultState();
+        private DisabledState mDisabledState = new DisabledState();
+        private EnabledState mEnabledState = new EnabledState();
+
+        @Override
+        protected String getMessageInfo(Message msg) {
+            return cmdToString(msg.what);
+        }
+
+        NsdStateMachine(String name) {
+            super(name);
+            addState(mDefaultState);
+                addState(mDisabledState, mDefaultState);
+                addState(mEnabledState, mDefaultState);
+            if (isNsdEnabled()) {
+                setInitialState(mEnabledState);
+            } else {
+                setInitialState(mDisabledState);
+            }
+            setProcessedMessagesSize(25);
+        }
+
+        class DefaultState extends State {
+            @Override
+            public boolean processMessage(Message msg) {
+                switch (msg.what) {
+                    case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
+                        if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
+                            AsyncChannel c = (AsyncChannel) msg.obj;
+                            if (DBG) Slog.d(TAG, "New client listening to asynchronous messages");
+                            c.sendMessage(AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED);
+                            ClientInfo cInfo = new ClientInfo(c, msg.replyTo);
+                            mClients.put(msg.replyTo, cInfo);
+                        } else {
+                            Slog.e(TAG, "Client connection failure, error=" + msg.arg1);
+                        }
+                        break;
+                    case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
+                        if (msg.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) {
+                            Slog.e(TAG, "Send failed, client connection lost");
+                        } else {
+                            if (DBG) Slog.d(TAG, "Client connection lost with reason: " + msg.arg1);
+                        }
+                        mClients.remove(msg.replyTo);
+                        break;
+                    case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
+                        AsyncChannel ac = new AsyncChannel();
+                        ac.connect(mContext, getHandler(), msg.replyTo);
+                        break;
+                    case NsdManager.DISCOVER_SERVICES:
+                        mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
+                                NsdManager.BUSY);
+                       break;
+                    case NsdManager.STOP_DISCOVERY:
+                            mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
+                                    NsdManager.ERROR);
+                        break;
+                    case NsdManager.REGISTER_SERVICE:
+                        mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
+                                NsdManager.ERROR);
+                        break;
+                    case NsdManager.UNREGISTER_SERVICE:
+                        mReplyChannel.replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
+                                NsdManager.ERROR);
+                        break;
+                    case NsdManager.RESOLVE_SERVICE:
+                        mReplyChannel.replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
+                                NsdManager.ERROR);
+                        break;
+                    case NsdManager.STOP_RESOLVE:
+                        mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
+                                NsdManager.ERROR);
+                        break;
+                    default:
+                        Slog.e(TAG, "Unhandled " + msg);
+                        return NOT_HANDLED;
+                }
+                return HANDLED;
+            }
+        }
+
+        class DisabledState extends State {
+            @Override
+            public void enter() {
+                sendNsdStateChangeBroadcast(false);
+            }
+
+            @Override
+            public boolean processMessage(Message msg) {
+                switch (msg.what) {
+                    case NsdManager.ENABLE:
+                        transitionTo(mEnabledState);
+                        break;
+                    default:
+                        return NOT_HANDLED;
+                }
+                return HANDLED;
+            }
+        }
+
+        class EnabledState extends State {
+            @Override
+            public void enter() {
+                sendNsdStateChangeBroadcast(true);
+                if (mClients.size() > 0) {
+                    startMDnsDaemon();
+                }
+            }
+
+            @Override
+            public void exit() {
+                if (mClients.size() > 0) {
+                    stopMDnsDaemon();
+                }
+            }
+
+            @Override
+            public boolean processMessage(Message msg) {
+                ClientInfo clientInfo;
+                DnsSdServiceInfo servInfo;
+                boolean result = HANDLED;
+                switch (msg.what) {
+                  case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
+                        //First client
+                        if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL &&
+                                mClients.size() == 0) {
+                            startMDnsDaemon();
+                        }
+                        result = NOT_HANDLED;
+                        break;
+                    case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
+                        //Last client
+                        if (mClients.size() == 1) {
+                            stopMDnsDaemon();
+                        }
+                        result = NOT_HANDLED;
+                        break;
+                    case NsdManager.DISABLE:
+                        //TODO: cleanup clients
+                        transitionTo(mDisabledState);
+                        break;
+                    case NsdManager.DISCOVER_SERVICES:
+                        if (DBG) Slog.d(TAG, "Discover services");
+                        servInfo = (DnsSdServiceInfo) msg.obj;
+                        clientInfo = mClients.get(msg.replyTo);
+                        if (clientInfo.mDiscoveryId != INVALID_ID) {
+                            //discovery already in progress
+                            if (DBG) Slog.d(TAG, "discovery in progress");
+                            mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
+                                    NsdManager.ALREADY_ACTIVE);
+                            break;
+                        }
+                        clientInfo.mDiscoveryId = getUniqueId();
+                        if (discoverServices(clientInfo.mDiscoveryId, servInfo.getServiceType())) {
+                            mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_STARTED);
+                        } else {
+                            mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
+                                    NsdManager.ERROR);
+                            clientInfo.mDiscoveryId = INVALID_ID;
+                        }
+                        break;
+                    case NsdManager.STOP_DISCOVERY:
+                        if (DBG) Slog.d(TAG, "Stop service discovery");
+                        clientInfo = mClients.get(msg.replyTo);
+                        if (clientInfo.mDiscoveryId == INVALID_ID) {
+                            //already stopped
+                            if (DBG) Slog.d(TAG, "discovery already stopped");
+                            mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
+                                    NsdManager.ALREADY_ACTIVE);
+                            break;
+                        }
+                        if (stopServiceDiscovery(clientInfo.mDiscoveryId)) {
+                            clientInfo.mDiscoveryId = INVALID_ID;
+                            mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_SUCCEEDED);
+                        } else {
+                            mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
+                                    NsdManager.ERROR);
+                        }
+                        break;
+                    case NsdManager.REGISTER_SERVICE:
+                        if (DBG) Slog.d(TAG, "Register service");
+                        clientInfo = mClients.get(msg.replyTo);
+                        if (clientInfo.mRegisteredIds.size() >= ClientInfo.MAX_REG) {
+                            if (DBG) Slog.d(TAG, "register service exceeds limit");
+                            mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
+                                    NsdManager.MAX_REGS_REACHED);
+                        }
+
+                        int id = getUniqueId();
+                        if (registerService(id, (DnsSdServiceInfo) msg.obj)) {
+                            clientInfo.mRegisteredIds.add(id);
+                        } else {
+                            mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
+                                    NsdManager.ERROR);
+                        }
+                        break;
+                    case NsdManager.UNREGISTER_SERVICE:
+                        if (DBG) Slog.d(TAG, "unregister service");
+                        clientInfo = mClients.get(msg.replyTo);
+                        int regId = msg.arg1;
+                        if (clientInfo.mRegisteredIds.remove(new Integer(regId)) &&
+                                unregisterService(regId)) {
+                            mReplyChannel.replyToMessage(msg,
+                                    NsdManager.UNREGISTER_SERVICE_SUCCEEDED);
+                        } else {
+                            mReplyChannel.replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
+                                    NsdManager.ERROR);
+                        }
+                        break;
+                    case NsdManager.UPDATE_SERVICE:
+                        if (DBG) Slog.d(TAG, "Update service");
+                        //TODO: implement
+                        mReplyChannel.replyToMessage(msg, NsdManager.UPDATE_SERVICE_FAILED);
+                        break;
+                    case NsdManager.RESOLVE_SERVICE:
+                        if (DBG) Slog.d(TAG, "Resolve service");
+                        servInfo = (DnsSdServiceInfo) msg.obj;
+                        clientInfo = mClients.get(msg.replyTo);
+                        if (clientInfo.mResolveId != INVALID_ID) {
+                            //first cancel existing resolve
+                            stopResolveService(clientInfo.mResolveId);
+                        }
+
+                        clientInfo.mResolveId = getUniqueId();
+                        if (!resolveService(clientInfo.mResolveId, servInfo)) {
+                            mReplyChannel.replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
+                                    NsdManager.ERROR);
+                            clientInfo.mResolveId = INVALID_ID;
+                        }
+                        break;
+                    case NsdManager.STOP_RESOLVE:
+                        if (DBG) Slog.d(TAG, "Stop resolve");
+                        clientInfo = mClients.get(msg.replyTo);
+                        if (clientInfo.mResolveId == INVALID_ID) {
+                            //already stopped
+                            if (DBG) Slog.d(TAG, "resolve already stopped");
+                            mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
+                                    NsdManager.ALREADY_ACTIVE);
+                            break;
+                        }
+                        if (stopResolveService(clientInfo.mResolveId)) {
+                            clientInfo.mResolveId = INVALID_ID;
+                            mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_SUCCEEDED);
+                        } else {
+                            mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
+                                    NsdManager.ERROR);
+                        }
+                        break;
+                    default:
+                        result = NOT_HANDLED;
+                        break;
+                }
+                return result;
+            }
+       }
+    }
 
     private NativeDaemonConnector mNativeConnector;
     private final CountDownLatch mNativeDaemonConnected = new CountDownLatch(1);
 
     private NsdService(Context context) {
         mContext = context;
-
-        HandlerThread nsdThread = new HandlerThread("NsdService");
-        nsdThread.start();
-        mAsyncServiceHandler = new AsyncServiceHandler(nsdThread.getLooper());
+        mContentResolver = context.getContentResolver();
 
         mNativeConnector = new NativeDaemonConnector(new NativeCallbackReceiver(), "mdns", 10,
                 MDNS_TAG, 25);
+
+        mNsdStateMachine = new NsdStateMachine(TAG);
+        mNsdStateMachine.start();
+
         Thread th = new Thread(mNativeConnector, MDNS_TAG);
         th.start();
     }
 
     public static NsdService create(Context context) throws InterruptedException {
         NsdService service = new NsdService(context);
-        /* service.mNativeDaemonConnected.await(); */
+        service.mNativeDaemonConnected.await();
         return service;
     }
 
     public Messenger getMessenger() {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INTERNET,
             "NsdService");
-        return new Messenger(mAsyncServiceHandler);
+        return new Messenger(mNsdStateMachine.getHandler());
+    }
+
+    public void setEnabled(boolean enable) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL,
+                "NsdService");
+        Settings.Secure.putInt(mContentResolver, Settings.Secure.NSD_ON, enable ? 1 : 0);
+        if (enable) {
+            mNsdStateMachine.sendMessage(NsdManager.ENABLE);
+        } else {
+            mNsdStateMachine.sendMessage(NsdManager.DISABLE);
+        }
+    }
+
+    private void sendNsdStateChangeBroadcast(boolean enabled) {
+        final Intent intent = new Intent(NsdManager.ACTION_NSD_STATE_CHANGED);
+        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+        if (enabled) {
+            intent.putExtra(NsdManager.EXTRA_NSD_STATE, NsdManager.NSD_STATE_ENABLED);
+        } else {
+            intent.putExtra(NsdManager.EXTRA_NSD_STATE, NsdManager.NSD_STATE_DISABLED);
+        }
+        mContext.sendStickyBroadcast(intent);
+    }
+
+    private boolean isNsdEnabled() {
+        boolean ret = Settings.Secure.getInt(mContentResolver, Settings.Secure.NSD_ON, 1) == 1;
+        if (DBG) Slog.d(TAG, "Network service discovery enabled " + ret);
+        return ret;
     }
 
     private int getUniqueId() {
@@ -522,7 +683,7 @@
     }
 
     @Override
-    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
                 != PackageManager.PERMISSION_GRANTED) {
             pw.println("Permission Denial: can't dump ServiceDiscoverService from from pid="
@@ -531,7 +692,12 @@
             return;
         }
 
-        pw.println("Internal state:");
+        for (ClientInfo client : mClients.values()) {
+            pw.println("Client Info");
+            pw.println(client);
+        }
+
+        mNsdStateMachine.dump(fd, pw, args);
     }
 
     private ClientInfo getClientByDiscovery(int discoveryId) {
@@ -579,5 +745,19 @@
             mDiscoveryId = mResolveId = INVALID_ID;
             if (DBG) Slog.d(TAG, "New client, channel: " + c + " messenger: " + m);
         }
+
+        @Override
+        public String toString() {
+            StringBuffer sb = new StringBuffer();
+            sb.append("mChannel ").append(mChannel).append("\n");
+            sb.append("mMessenger ").append(mMessenger).append("\n");
+            sb.append("mDiscoveryId ").append(mDiscoveryId).append("\n");
+            sb.append("mResolveId ").append(mResolveId).append("\n");
+            sb.append("mResolvedService ").append(mResolvedService).append("\n");
+            for(int regId : mRegisteredIds) {
+                sb.append("regId ").append(regId).append("\n");
+            }
+            return sb.toString();
+        }
     }
 }
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index 2a67e02..f53e957 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -420,6 +420,7 @@
     @Override
     public INetworkStatsSession openSession() {
         mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
+        assertBandwidthControlEnabled();
 
         // return an IBinder which holds strong references to any loaded stats
         // for its lifetime; when caller closes only weak references remain.
@@ -486,6 +487,7 @@
     @Override
     public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
         mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
+        assertBandwidthControlEnabled();
         return mDevStatsCached.getSummary(template, start, end).getTotalBytes();
     }
 
@@ -494,6 +496,7 @@
         if (Binder.getCallingUid() != uid) {
             mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
         }
+        assertBandwidthControlEnabled();
 
         // TODO: switch to data layer stats once kernel exports
         // for now, read network layer stats and flatten across all ifaces
@@ -565,6 +568,7 @@
     @Override
     public void forceUpdate() {
         mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
+        assertBandwidthControlEnabled();
 
         final long token = Binder.clearCallingIdentity();
         try {
@@ -1039,6 +1043,12 @@
         }
     };
 
+    private void assertBandwidthControlEnabled() {
+        if (!isBandwidthControlEnabled()) {
+            throw new IllegalStateException("Bandwidth module disabled");
+        }
+    }
+
     private boolean isBandwidthControlEnabled() {
         try {
             return mNetworkManager.isBandwidthControlEnabled();
