FileDocCategorySizeDatePackage
NsdService.javaAPI DocAndroid 5.1 API40954Thu Mar 12 22:22:42 GMT 2015com.android.server

NsdService

public class NsdService extends INsdManager.Stub
Network Service Discovery Service handles remote service discovery operation requests by implementing the INsdManager interface.
hide

Fields Summary
private static final String
TAG
private static final String
MDNS_TAG
private static final boolean
DBG
private android.content.Context
mContext
private android.content.ContentResolver
mContentResolver
private NsdStateMachine
mNsdStateMachine
private HashMap
mClients
Clients receiving asynchronous messages
private android.util.SparseArray
mIdToClientInfoMap
private com.android.internal.util.AsyncChannel
mReplyChannel
private int
INVALID_ID
private int
mUniqueId
private static final int
BASE
private static final int
CMD_TO_STRING_COUNT
private static String[]
sCmdToString
private NativeDaemonConnector
mNativeConnector
private final CountDownLatch
mNativeDaemonConnected
Constructors Summary
private NsdService(android.content.Context context)


       
        mContext = context;
        mContentResolver = context.getContentResolver();

        mNativeConnector = new NativeDaemonConnector(new NativeCallbackReceiver(), "mdns", 10,
                MDNS_TAG, 25, null);

        mNsdStateMachine = new NsdStateMachine(TAG);
        mNsdStateMachine.start();

        Thread th = new Thread(mNativeConnector, MDNS_TAG);
        th.start();
    
Methods Summary
private static java.lang.StringcmdToString(int cmd)


     
        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";
    
        cmd -= BASE;
        if ((cmd >= 0) && (cmd < sCmdToString.length)) {
            return sCmdToString[cmd];
        } else {
            return null;
        }
    
public static com.android.server.NsdServicecreate(android.content.Context context)

        NsdService service = new NsdService(context);
        service.mNativeDaemonConnected.await();
        return service;
    
private booleandiscoverServices(int discoveryId, java.lang.String serviceType)

        if (DBG) Slog.d(TAG, "discoverServices: " + discoveryId + " " + serviceType);
        try {
            mNativeConnector.execute("mdnssd", "discover", discoveryId, serviceType);
        } catch(NativeDaemonConnectorException e) {
            Slog.e(TAG, "Failed to discoverServices " + e);
            return false;
        }
        return true;
    
public voiddump(java.io.FileDescriptor fd, java.io.PrintWriter pw, java.lang.String[] args)

        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
                != PackageManager.PERMISSION_GRANTED) {
            pw.println("Permission Denial: can't dump ServiceDiscoverService from from pid="
                    + Binder.getCallingPid()
                    + ", uid=" + Binder.getCallingUid());
            return;
        }

        for (ClientInfo client : mClients.values()) {
            pw.println("Client Info");
            pw.println(client);
        }

        mNsdStateMachine.dump(fd, pw, args);
    
private booleangetAddrInfo(int resolveId, java.lang.String hostname)

        if (DBG) Slog.d(TAG, "getAdddrInfo: " + resolveId);
        try {
            mNativeConnector.execute("mdnssd", "getaddrinfo", resolveId, hostname);
        } catch(NativeDaemonConnectorException e) {
            Slog.e(TAG, "Failed to getAddrInfo " + e);
            return false;
        }
        return true;
    
public android.os.MessengergetMessenger()

        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INTERNET,
            "NsdService");
        return new Messenger(mNsdStateMachine.getHandler());
    
private intgetUniqueId()

        if (++mUniqueId == INVALID_ID) return ++mUniqueId;
        return mUniqueId;
    
private booleanisNsdEnabled()

        boolean ret = Settings.Global.getInt(mContentResolver, Settings.Global.NSD_ON, 1) == 1;
        if (DBG) Slog.d(TAG, "Network service discovery enabled " + ret);
        return ret;
    
private android.os.MessageobtainMessage(android.os.Message srcMsg)

        Message msg = Message.obtain();
        msg.arg2 = srcMsg.arg2;
        return msg;
    
private booleanregisterService(int regId, android.net.nsd.NsdServiceInfo service)

        if (DBG) Slog.d(TAG, "registerService: " + regId + " " + service);
        try {
            Command cmd = new Command("mdnssd", "register", regId, service.getServiceName(),
                    service.getServiceType(), service.getPort());

            // Add TXT records as additional arguments.
            Map<String, byte[]> txtRecords = service.getAttributes();
            for (String key : txtRecords.keySet()) {
                try {
                    // TODO: Send encoded TXT record as bytes once NDC/netd supports binary data.
                    byte[] recordValue = txtRecords.get(key);
                    cmd.appendArg(String.format(Locale.US, "%s=%s", key,
                            recordValue != null ? new String(recordValue, "UTF_8") : ""));
                } catch (UnsupportedEncodingException e) {
                    Slog.e(TAG, "Failed to encode txtRecord " + e);
                }
            }

            mNativeConnector.execute(cmd);
        } catch(NativeDaemonConnectorException e) {
            Slog.e(TAG, "Failed to execute registerService " + e);
            return false;
        }
        return true;
    
private voidreplyToMessage(android.os.Message msg, int what)

        if (msg.replyTo == null) return;
        Message dstMsg = obtainMessage(msg);
        dstMsg.what = what;
        mReplyChannel.replyToMessage(msg, dstMsg);
    
private voidreplyToMessage(android.os.Message msg, int what, int arg1)

        if (msg.replyTo == null) return;
        Message dstMsg = obtainMessage(msg);
        dstMsg.what = what;
        dstMsg.arg1 = arg1;
        mReplyChannel.replyToMessage(msg, dstMsg);
    
private voidreplyToMessage(android.os.Message msg, int what, java.lang.Object obj)

        if (msg.replyTo == null) return;
        Message dstMsg = obtainMessage(msg);
        dstMsg.what = what;
        dstMsg.obj = obj;
        mReplyChannel.replyToMessage(msg, dstMsg);
    
private booleanresolveService(int resolveId, android.net.nsd.NsdServiceInfo service)

        if (DBG) Slog.d(TAG, "resolveService: " + resolveId + " " + service);
        try {
            mNativeConnector.execute("mdnssd", "resolve", resolveId, service.getServiceName(),
                    service.getServiceType(), "local.");
        } catch(NativeDaemonConnectorException e) {
            Slog.e(TAG, "Failed to resolveService " + e);
            return false;
        }
        return true;
    
private voidsendNsdStateChangeBroadcast(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.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
    
public voidsetEnabled(boolean enable)

        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL,
                "NsdService");
        Settings.Global.putInt(mContentResolver, Settings.Global.NSD_ON, enable ? 1 : 0);
        if (enable) {
            mNsdStateMachine.sendMessage(NsdManager.ENABLE);
        } else {
            mNsdStateMachine.sendMessage(NsdManager.DISABLE);
        }
    
private booleanstartMDnsDaemon()

        if (DBG) Slog.d(TAG, "startMDnsDaemon");
        try {
            mNativeConnector.execute("mdnssd", "start-service");
        } catch(NativeDaemonConnectorException e) {
            Slog.e(TAG, "Failed to start daemon" + e);
            return false;
        }
        return true;
    
private booleanstopGetAddrInfo(int resolveId)

        if (DBG) Slog.d(TAG, "stopGetAdddrInfo: " + resolveId);
        try {
            mNativeConnector.execute("mdnssd", "stop-getaddrinfo", resolveId);
        } catch(NativeDaemonConnectorException e) {
            Slog.e(TAG, "Failed to stopGetAddrInfo " + e);
            return false;
        }
        return true;
    
private booleanstopMDnsDaemon()

        if (DBG) Slog.d(TAG, "stopMDnsDaemon");
        try {
            mNativeConnector.execute("mdnssd", "stop-service");
        } catch(NativeDaemonConnectorException e) {
            Slog.e(TAG, "Failed to start daemon" + e);
            return false;
        }
        return true;
    
private booleanstopResolveService(int resolveId)

        if (DBG) Slog.d(TAG, "stopResolveService: " + resolveId);
        try {
            mNativeConnector.execute("mdnssd", "stop-resolve", resolveId);
        } catch(NativeDaemonConnectorException e) {
            Slog.e(TAG, "Failed to stop resolve " + e);
            return false;
        }
        return true;
    
private booleanstopServiceDiscovery(int discoveryId)

        if (DBG) Slog.d(TAG, "stopServiceDiscovery: " + discoveryId);
        try {
            mNativeConnector.execute("mdnssd", "stop-discover", discoveryId);
        } catch(NativeDaemonConnectorException e) {
            Slog.e(TAG, "Failed to stopServiceDiscovery " + e);
            return false;
        }
        return true;
    
private java.lang.Stringunescape(java.lang.String s)

        StringBuilder sb = new StringBuilder(s.length());
        for (int i = 0; i < s.length(); ++i) {
            char c = s.charAt(i);
            if (c == '\\") {
                if (++i >= s.length()) {
                    Slog.e(TAG, "Unexpected end of escape sequence in: " + s);
                    break;
                }
                c = s.charAt(i);
                if (c != '." && c != '\\") {
                    if (i + 2 >= s.length()) {
                        Slog.e(TAG, "Unexpected end of escape sequence in: " + s);
                        break;
                    }
                    c = (char) ((c-'0") * 100 + (s.charAt(i+1)-'0") * 10 + (s.charAt(i+2)-'0"));
                    i += 2;
                }
            }
            sb.append(c);
        }
        return sb.toString();
    
private booleanunregisterService(int regId)

        if (DBG) Slog.d(TAG, "unregisterService: " + regId);
        try {
            mNativeConnector.execute("mdnssd", "stop-register", regId);
        } catch(NativeDaemonConnectorException e) {
            Slog.e(TAG, "Failed to execute unregisterService " + e);
            return false;
        }
        return true;
    
private booleanupdateService(int regId, android.net.nsd.DnsSdTxtRecord t)

        if (DBG) Slog.d(TAG, "updateService: " + regId + " " + t);
        try {
            if (t == null) return false;
            mNativeConnector.execute("mdnssd", "update", regId, t.size(), t.getRawData());
        } catch(NativeDaemonConnectorException e) {
            Slog.e(TAG, "Failed to updateServices " + e);
            return false;
        }
        return true;