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

Commit 888ec76b authored by Luke Huang's avatar Luke Huang Committed by Automerger Merge Worker
Browse files

Merge "Make NsdService only start the native daemon when needed and...

Merge "Make NsdService only start the native daemon when needed and automatically clean it up." into sc-dev am: c85827a9

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14962980

Change-Id: I5ebaac9071d967281b389116235508bb7cea96e9
parents 9fe303b8 c85827a9
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -199,6 +199,9 @@ public final class NsdManager {
    /** @hide */
    /** @hide */
    public static final int RESOLVE_SERVICE_SUCCEEDED               = BASE + 20;
    public static final int RESOLVE_SERVICE_SUCCEEDED               = BASE + 20;


    /** @hide */
    public static final int DAEMON_CLEANUP                          = BASE + 21;

    /** @hide */
    /** @hide */
    public static final int ENABLE                                  = BASE + 24;
    public static final int ENABLE                                  = BASE + 24;
    /** @hide */
    /** @hide */
+63 −19
Original line number Original line Diff line number Diff line
@@ -61,6 +61,7 @@ public class NsdService extends INsdManager.Stub {
    private static final String MDNS_TAG = "mDnsConnector";
    private static final String MDNS_TAG = "mDnsConnector";


    private static final boolean DBG = true;
    private static final boolean DBG = true;
    private static final long CLEANUP_DELAY_MS = 3000;


    private final Context mContext;
    private final Context mContext;
    private final NsdSettings mNsdSettings;
    private final NsdSettings mNsdSettings;
@@ -77,6 +78,7 @@ public class NsdService extends INsdManager.Stub {
    private final SparseArray<ClientInfo> mIdToClientInfoMap= new SparseArray<>();
    private final SparseArray<ClientInfo> mIdToClientInfoMap= new SparseArray<>();


    private final AsyncChannel mReplyChannel = new AsyncChannel();
    private final AsyncChannel mReplyChannel = new AsyncChannel();
    private final long mCleanupDelayMs;


    private static final int INVALID_ID = 0;
    private static final int INVALID_ID = 0;
    private int mUniqueId = 1;
    private int mUniqueId = 1;
@@ -92,6 +94,22 @@ public class NsdService extends INsdManager.Stub {
            return NsdManager.nameOf(what);
            return NsdManager.nameOf(what);
        }
        }


        void maybeStartDaemon() {
            mDaemon.maybeStart();
            maybeScheduleStop();
        }

        void maybeScheduleStop() {
            if (!isAnyRequestActive()) {
                cancelStop();
                sendMessageDelayed(NsdManager.DAEMON_CLEANUP, mCleanupDelayMs);
            }
        }

        void cancelStop() {
            this.removeMessages(NsdManager.DAEMON_CLEANUP);
        }

        /**
        /**
         * Observes the NSD on/off setting, and takes action when changed.
         * Observes the NSD on/off setting, and takes action when changed.
         */
         */
@@ -151,10 +169,6 @@ public class NsdService extends INsdManager.Stub {
                            cInfo.expungeAllRequests();
                            cInfo.expungeAllRequests();
                            mClients.remove(msg.replyTo);
                            mClients.remove(msg.replyTo);
                        }
                        }
                        //Last client
                        if (mClients.size() == 0) {
                            mDaemon.stop();
                        }
                        break;
                        break;
                    case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
                    case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
                        AsyncChannel ac = new AsyncChannel();
                        AsyncChannel ac = new AsyncChannel();
@@ -180,6 +194,9 @@ public class NsdService extends INsdManager.Stub {
                        replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
                        replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
                                NsdManager.FAILURE_INTERNAL_ERROR);
                                NsdManager.FAILURE_INTERNAL_ERROR);
                        break;
                        break;
                    case NsdManager.DAEMON_CLEANUP:
                        mDaemon.maybeStop();
                        break;
                    case NsdManager.NATIVE_DAEMON_EVENT:
                    case NsdManager.NATIVE_DAEMON_EVENT:
                    default:
                    default:
                        Slog.e(TAG, "Unhandled " + msg);
                        Slog.e(TAG, "Unhandled " + msg);
@@ -212,16 +229,13 @@ public class NsdService extends INsdManager.Stub {
            @Override
            @Override
            public void enter() {
            public void enter() {
                sendNsdStateChangeBroadcast(true);
                sendNsdStateChangeBroadcast(true);
                if (mClients.size() > 0) {
                    mDaemon.start();
                }
            }
            }


            @Override
            @Override
            public void exit() {
            public void exit() {
                if (mClients.size() > 0) {
                // TODO: it is incorrect to stop the daemon without expunging all requests
                    mDaemon.stop();
                // and sending error callbacks to clients.
                }
                maybeScheduleStop();
            }
            }


            private boolean requestLimitReached(ClientInfo clientInfo) {
            private boolean requestLimitReached(ClientInfo clientInfo) {
@@ -236,12 +250,15 @@ public class NsdService extends INsdManager.Stub {
                clientInfo.mClientIds.put(clientId, globalId);
                clientInfo.mClientIds.put(clientId, globalId);
                clientInfo.mClientRequests.put(clientId, what);
                clientInfo.mClientRequests.put(clientId, what);
                mIdToClientInfoMap.put(globalId, clientInfo);
                mIdToClientInfoMap.put(globalId, clientInfo);
                // Remove the cleanup event because here comes a new request.
                cancelStop();
            }
            }


            private void removeRequestMap(int clientId, int globalId, ClientInfo clientInfo) {
            private void removeRequestMap(int clientId, int globalId, ClientInfo clientInfo) {
                clientInfo.mClientIds.delete(clientId);
                clientInfo.mClientIds.delete(clientId);
                clientInfo.mClientRequests.delete(clientId);
                clientInfo.mClientRequests.delete(clientId);
                mIdToClientInfoMap.remove(globalId);
                mIdToClientInfoMap.remove(globalId);
                maybeScheduleStop();
            }
            }


            @Override
            @Override
@@ -251,14 +268,12 @@ public class NsdService extends INsdManager.Stub {
                int id;
                int id;
                switch (msg.what) {
                switch (msg.what) {
                    case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
                    case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
                        //First client
                        if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL &&
                                mClients.size() == 0) {
                            mDaemon.start();
                        }
                        return NOT_HANDLED;
                        return NOT_HANDLED;
                    case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
                    case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
                        return NOT_HANDLED;
                        return NOT_HANDLED;
                }

                switch (msg.what) {
                    case NsdManager.DISABLE:
                    case NsdManager.DISABLE:
                        //TODO: cleanup clients
                        //TODO: cleanup clients
                        transitionTo(mDisabledState);
                        transitionTo(mDisabledState);
@@ -274,6 +289,7 @@ public class NsdService extends INsdManager.Stub {
                            break;
                            break;
                        }
                        }


                        maybeStartDaemon();
                        id = getUniqueId();
                        id = getUniqueId();
                        if (discoverServices(id, servInfo.getServiceType())) {
                        if (discoverServices(id, servInfo.getServiceType())) {
                            if (DBG) {
                            if (DBG) {
@@ -316,6 +332,7 @@ public class NsdService extends INsdManager.Stub {
                            break;
                            break;
                        }
                        }


                        maybeStartDaemon();
                        id = getUniqueId();
                        id = getUniqueId();
                        if (registerService(id, (NsdServiceInfo) msg.obj)) {
                        if (registerService(id, (NsdServiceInfo) msg.obj)) {
                            if (DBG) Slog.d(TAG, "Register " + msg.arg2 + " " + id);
                            if (DBG) Slog.d(TAG, "Register " + msg.arg2 + " " + id);
@@ -357,6 +374,7 @@ public class NsdService extends INsdManager.Stub {
                            break;
                            break;
                        }
                        }


                        maybeStartDaemon();
                        id = getUniqueId();
                        id = getUniqueId();
                        if (resolveService(id, servInfo)) {
                        if (resolveService(id, servInfo)) {
                            clientInfo.mResolvedService = new NsdServiceInfo();
                            clientInfo.mResolvedService = new NsdServiceInfo();
@@ -513,6 +531,10 @@ public class NsdService extends INsdManager.Stub {
       }
       }
    }
    }


    private boolean isAnyRequestActive() {
        return mIdToClientInfoMap.size() != 0;
    }

    private String unescape(String s) {
    private String unescape(String s) {
        StringBuilder sb = new StringBuilder(s.length());
        StringBuilder sb = new StringBuilder(s.length());
        for (int i = 0; i < s.length(); ++i) {
        for (int i = 0; i < s.length(); ++i) {
@@ -538,7 +560,9 @@ public class NsdService extends INsdManager.Stub {
    }
    }


    @VisibleForTesting
    @VisibleForTesting
    NsdService(Context ctx, NsdSettings settings, Handler handler, DaemonConnectionSupplier fn) {
    NsdService(Context ctx, NsdSettings settings, Handler handler,
            DaemonConnectionSupplier fn, long cleanupDelayMs) {
        mCleanupDelayMs = cleanupDelayMs;
        mContext = ctx;
        mContext = ctx;
        mNsdSettings = settings;
        mNsdSettings = settings;
        mNsdStateMachine = new NsdStateMachine(TAG, handler);
        mNsdStateMachine = new NsdStateMachine(TAG, handler);
@@ -552,7 +576,8 @@ public class NsdService extends INsdManager.Stub {
        HandlerThread thread = new HandlerThread(TAG);
        HandlerThread thread = new HandlerThread(TAG);
        thread.start();
        thread.start();
        Handler handler = new Handler(thread.getLooper());
        Handler handler = new Handler(thread.getLooper());
        NsdService service = new NsdService(context, settings, handler, DaemonConnection::new);
        NsdService service = new NsdService(context, settings, handler,
                DaemonConnection::new, CLEANUP_DELAY_MS);
        service.mDaemonCallback.awaitConnection();
        service.mDaemonCallback.awaitConnection();
        return service;
        return service;
    }
    }
@@ -681,12 +706,16 @@ public class NsdService extends INsdManager.Stub {
    @VisibleForTesting
    @VisibleForTesting
    public static class DaemonConnection {
    public static class DaemonConnection {
        final NativeDaemonConnector mNativeConnector;
        final NativeDaemonConnector mNativeConnector;
        boolean mIsStarted = false;


        DaemonConnection(NativeCallbackReceiver callback) {
        DaemonConnection(NativeCallbackReceiver callback) {
            mNativeConnector = new NativeDaemonConnector(callback, "mdns", 10, MDNS_TAG, 25, null);
            mNativeConnector = new NativeDaemonConnector(callback, "mdns", 10, MDNS_TAG, 25, null);
            new Thread(mNativeConnector, MDNS_TAG).start();
            new Thread(mNativeConnector, MDNS_TAG).start();
        }
        }


        /**
         * Executes the specified cmd on the daemon.
         */
        public boolean execute(Object... args) {
        public boolean execute(Object... args) {
            if (DBG) {
            if (DBG) {
                Slog.d(TAG, "mdnssd " + Arrays.toString(args));
                Slog.d(TAG, "mdnssd " + Arrays.toString(args));
@@ -700,12 +729,26 @@ public class NsdService extends INsdManager.Stub {
            return true;
            return true;
        }
        }


        public void start() {
        /**
         * Starts the daemon if it is not already started.
         */
        public void maybeStart() {
            if (mIsStarted) {
                return;
            }
            execute("start-service");
            execute("start-service");
            mIsStarted = true;
        }
        }


        public void stop() {
        /**
         * Stops the daemon if it is started.
         */
        public void maybeStop() {
            if (!mIsStarted) {
                return;
            }
            execute("stop-service");
            execute("stop-service");
            mIsStarted = false;
        }
        }
    }
    }


@@ -864,6 +907,7 @@ public class NsdService extends INsdManager.Stub {
            }
            }
            mClientIds.clear();
            mClientIds.clear();
            mClientRequests.clear();
            mClientRequests.clear();
            mNsdStateMachine.maybeScheduleStop();
        }
        }


        // mClientIds is a sparse array of listener id -> mDnsClient id.  For a given mDnsClient id,
        // mClientIds is a sparse array of listener id -> mDnsClient id.  For a given mDnsClient id,