Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 88fe4ebc authored by Irfan Sheriff's avatar Irfan Sheriff Committed by Gerrit Code Review
Browse files

Merge "NsdService: Clear client info after resolution request is serviced."

parents fc56015b 6727e735
Loading
Loading
Loading
Loading
+129 −123
Original line number Original line Diff line number Diff line
@@ -389,8 +389,10 @@ public class NsdService extends INsdManager.Stub {
                        break;
                        break;
                    case NsdManager.NATIVE_DAEMON_EVENT:
                    case NsdManager.NATIVE_DAEMON_EVENT:
                        NativeEvent event = (NativeEvent) msg.obj;
                        NativeEvent event = (NativeEvent) msg.obj;
                        handleNativeEvent(event.code, event.raw,
                        if (!handleNativeEvent(event.code, event.raw,
                                NativeDaemonEvent.unescapeArgs(event.raw));
                                NativeDaemonEvent.unescapeArgs(event.raw))) {
                            result = NOT_HANDLED;
                        }
                        break;
                        break;
                    default:
                    default:
                        result = NOT_HANDLED;
                        result = NOT_HANDLED;
@@ -398,121 +400,16 @@ public class NsdService extends INsdManager.Stub {
                }
                }
                return result;
                return result;
            }
            }
       }
    }

    private NativeDaemonConnector mNativeConnector;
    private final CountDownLatch mNativeDaemonConnected = new CountDownLatch(1);

    private NsdService(Context context) {
        mContext = context;
        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();
        return service;
    }

    public Messenger getMessenger() {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INTERNET,
            "NsdService");
        return new Messenger(mNsdStateMachine.getHandler());
    }

    public void setEnabled(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 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.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
    }

    private boolean isNsdEnabled() {
        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 int getUniqueId() {
        if (++mUniqueId == INVALID_ID) return ++mUniqueId;
        return mUniqueId;
    }

    /* These should be in sync with system/netd/mDnsResponseCode.h */
    class NativeResponseCode {
        public static final int SERVICE_DISCOVERY_FAILED    =   602;
        public static final int SERVICE_FOUND               =   603;
        public static final int SERVICE_LOST                =   604;

        public static final int SERVICE_REGISTRATION_FAILED =   605;
        public static final int SERVICE_REGISTERED          =   606;

        public static final int SERVICE_RESOLUTION_FAILED   =   607;
        public static final int SERVICE_RESOLVED            =   608;

        public static final int SERVICE_UPDATED             =   609;
        public static final int SERVICE_UPDATE_FAILED       =   610;

        public static final int SERVICE_GET_ADDR_FAILED     =   611;
        public static final int SERVICE_GET_ADDR_SUCCESS    =   612;
    }

    private class NativeEvent {
        int code;
        String raw;

        NativeEvent(int code, String raw) {
            this.code = code;
            this.raw = raw;
        }
    }

    class NativeCallbackReceiver implements INativeDaemonConnectorCallbacks {
        public void onDaemonConnected() {
            mNativeDaemonConnected.countDown();
        }

        public boolean onEvent(int code, String raw, String[] cooked) {
            // TODO: NDC translates a message to a callback, we could enhance NDC to
            // directly interact with a state machine through messages
            NativeEvent event = new NativeEvent(code, raw);
            mNsdStateMachine.sendMessage(NsdManager.NATIVE_DAEMON_EVENT, event);
            return true;
        }
    }


    private void handleNativeEvent(int code, String raw, String[] cooked) {
            private boolean handleNativeEvent(int code, String raw, String[] cooked) {
                boolean handled = true;
                NsdServiceInfo servInfo;
                NsdServiceInfo servInfo;
                int id = Integer.parseInt(cooked[1]);
                int id = Integer.parseInt(cooked[1]);
                ClientInfo clientInfo = mIdToClientInfoMap.get(id);
                ClientInfo clientInfo = mIdToClientInfoMap.get(id);
                if (clientInfo == null) {
                if (clientInfo == null) {
                    Slog.e(TAG, "Unique id with no client mapping: " + id);
                    Slog.e(TAG, "Unique id with no client mapping: " + id);
            return;
                    handled = false;
                    return handled;
                }
                }


                /* This goes in response as msg.arg2 */
                /* This goes in response as msg.arg2 */
@@ -581,7 +478,7 @@ public class NsdService extends INsdManager.Stub {
                        if (!getAddrInfo(id, cooked[3])) {
                        if (!getAddrInfo(id, cooked[3])) {
                            clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
                            clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
                                    NsdManager.FAILURE_INTERNAL_ERROR, clientId);
                                    NsdManager.FAILURE_INTERNAL_ERROR, clientId);
                    mIdToClientInfoMap.remove(id);
                            removeRequestMap(clientId, id, clientInfo);
                            clientInfo.mResolvedService = null;
                            clientInfo.mResolvedService = null;
                        }
                        }
                        break;
                        break;
@@ -589,7 +486,7 @@ public class NsdService extends INsdManager.Stub {
                        /* NNN resolveId errorCode */
                        /* NNN resolveId errorCode */
                        if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw);
                        if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw);
                        stopResolveService(id);
                        stopResolveService(id);
                mIdToClientInfoMap.remove(id);
                        removeRequestMap(clientId, id, clientInfo);
                        clientInfo.mResolvedService = null;
                        clientInfo.mResolvedService = null;
                        clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
                        clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
                                NsdManager.FAILURE_INTERNAL_ERROR, clientId);
                                NsdManager.FAILURE_INTERNAL_ERROR, clientId);
@@ -597,7 +494,7 @@ public class NsdService extends INsdManager.Stub {
                    case NativeResponseCode.SERVICE_GET_ADDR_FAILED:
                    case NativeResponseCode.SERVICE_GET_ADDR_FAILED:
                        /* NNN resolveId errorCode */
                        /* NNN resolveId errorCode */
                        stopGetAddrInfo(id);
                        stopGetAddrInfo(id);
                mIdToClientInfoMap.remove(id);
                        removeRequestMap(clientId, id, clientInfo);
                        clientInfo.mResolvedService = null;
                        clientInfo.mResolvedService = null;
                        if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw);
                        if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw);
                        clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
                        clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
@@ -615,12 +512,121 @@ public class NsdService extends INsdManager.Stub {
                                    NsdManager.FAILURE_INTERNAL_ERROR, clientId);
                                    NsdManager.FAILURE_INTERNAL_ERROR, clientId);
                        }
                        }
                        stopGetAddrInfo(id);
                        stopGetAddrInfo(id);
                mIdToClientInfoMap.remove(id);
                        removeRequestMap(clientId, id, clientInfo);
                        clientInfo.mResolvedService = null;
                        clientInfo.mResolvedService = null;
                        break;
                        break;
                    default:
                    default:
                        handled = false;
                        break;
                        break;
                }
                }
                return handled;
            }
       }
    }

    private NativeDaemonConnector mNativeConnector;
    private final CountDownLatch mNativeDaemonConnected = new CountDownLatch(1);

    private NsdService(Context context) {
        mContext = context;
        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();
        return service;
    }

    public Messenger getMessenger() {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INTERNET,
            "NsdService");
        return new Messenger(mNsdStateMachine.getHandler());
    }

    public void setEnabled(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 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.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
    }

    private boolean isNsdEnabled() {
        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 int getUniqueId() {
        if (++mUniqueId == INVALID_ID) return ++mUniqueId;
        return mUniqueId;
    }

    /* These should be in sync with system/netd/mDnsResponseCode.h */
    class NativeResponseCode {
        public static final int SERVICE_DISCOVERY_FAILED    =   602;
        public static final int SERVICE_FOUND               =   603;
        public static final int SERVICE_LOST                =   604;

        public static final int SERVICE_REGISTRATION_FAILED =   605;
        public static final int SERVICE_REGISTERED          =   606;

        public static final int SERVICE_RESOLUTION_FAILED   =   607;
        public static final int SERVICE_RESOLVED            =   608;

        public static final int SERVICE_UPDATED             =   609;
        public static final int SERVICE_UPDATE_FAILED       =   610;

        public static final int SERVICE_GET_ADDR_FAILED     =   611;
        public static final int SERVICE_GET_ADDR_SUCCESS    =   612;
    }

    private class NativeEvent {
        final int code;
        final String raw;

        NativeEvent(int code, String raw) {
            this.code = code;
            this.raw = raw;
        }
    }

    class NativeCallbackReceiver implements INativeDaemonConnectorCallbacks {
        public void onDaemonConnected() {
            mNativeDaemonConnected.countDown();
        }

        public boolean onEvent(int code, String raw, String[] cooked) {
            // TODO: NDC translates a message to a callback, we could enhance NDC to
            // directly interact with a state machine through messages
            NativeEvent event = new NativeEvent(code, raw);
            mNsdStateMachine.sendMessage(NsdManager.NATIVE_DAEMON_EVENT, event);
            return true;
        }
    }
    }


    private boolean startMDnsDaemon() {
    private boolean startMDnsDaemon() {
@@ -801,8 +807,8 @@ public class NsdService extends INsdManager.Stub {
    private class ClientInfo {
    private class ClientInfo {


        private static final int MAX_LIMIT = 10;
        private static final int MAX_LIMIT = 10;
        private AsyncChannel mChannel;
        private final AsyncChannel mChannel;
        private Messenger mMessenger;
        private final Messenger mMessenger;
        /* Remembers a resolved service until getaddrinfo completes */
        /* Remembers a resolved service until getaddrinfo completes */
        private NsdServiceInfo mResolvedService;
        private NsdServiceInfo mResolvedService;