Loading services/core/java/com/android/server/NsdService.java +45 −15 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ import android.net.nsd.DnsSdTxtRecord; import android.net.nsd.INsdManager; import android.net.nsd.NsdManager; import android.os.Binder; import android.os.HandlerThread; import android.os.Handler; import android.os.Message; import android.os.Messenger; import android.os.UserHandle; Loading @@ -40,6 +42,7 @@ import java.net.InetAddress; import java.util.HashMap; import java.util.concurrent.CountDownLatch; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.AsyncChannel; import com.android.internal.util.Protocol; import com.android.internal.util.State; Loading @@ -59,7 +62,7 @@ public class NsdService extends INsdManager.Stub { private static final boolean DBG = true; private final Context mContext; private final ContentResolver mContentResolver; private final NsdSettings mNsdSettings; private final NsdStateMachine mNsdStateMachine; private final NativeDaemonConnector mNativeConnector; private final CountDownLatch mNativeDaemonConnected = new CountDownLatch(1); Loading Loading @@ -108,8 +111,8 @@ public class NsdService extends INsdManager.Stub { false, contentObserver); } NsdStateMachine(String name) { super(name); NsdStateMachine(String name, Handler handler) { super(name, handler); addState(mDefaultState); addState(mDisabledState, mDefaultState); addState(mEnabledState, mDefaultState); Loading Loading @@ -541,14 +544,15 @@ public class NsdService extends INsdManager.Stub { return sb.toString(); } private NsdService(Context context) { mContext = context; mContentResolver = context.getContentResolver(); @VisibleForTesting NsdService(Context ctx, NsdSettings settings, Handler handler) { mContext = ctx; mNsdSettings = settings; mNativeConnector = new NativeDaemonConnector(new NativeCallbackReceiver(), "mdns", 10, MDNS_TAG, 25, null); NativeCallbackReceiver callback = new NativeCallbackReceiver(); mNativeConnector = new NativeDaemonConnector(callback, "mdns", 10, MDNS_TAG, 25, null); mNsdStateMachine = new NsdStateMachine(TAG); mNsdStateMachine = new NsdStateMachine(TAG, handler); mNsdStateMachine.start(); Thread th = new Thread(mNativeConnector, MDNS_TAG); Loading @@ -556,21 +560,24 @@ public class NsdService extends INsdManager.Stub { } public static NsdService create(Context context) throws InterruptedException { NsdService service = new NsdService(context); NsdSettings settings = NsdSettings.makeDefault(context); HandlerThread thread = new HandlerThread(TAG); thread.start(); Handler handler = new Handler(thread.getLooper()); NsdService service = new NsdService(context, settings, handler); service.mNativeDaemonConnected.await(); return service; } public Messenger getMessenger() { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INTERNET, "NsdService"); 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); mNsdSettings.putEnabledStatus(enable); if (enable) { mNsdStateMachine.sendMessage(NsdManager.ENABLE); } else { Loading @@ -590,8 +597,10 @@ public class NsdService extends INsdManager.Stub { } 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); boolean ret = mNsdSettings.isEnabled(); if (DBG) { Slog.d(TAG, "Network service discovery is " + (ret ? "enabled" : "disabled")); } return ret; } Loading Loading @@ -927,4 +936,25 @@ public class NsdService extends INsdManager.Stub { return -1; } } @VisibleForTesting public interface NsdSettings { boolean isEnabled(); void putEnabledStatus(boolean isEnabled); static NsdSettings makeDefault(Context context) { ContentResolver resolver = context.getContentResolver(); return new NsdSettings() { @Override public boolean isEnabled() { return Settings.Global.getInt(resolver, Settings.Global.NSD_ON, 1) == 1; } @Override public void putEnabledStatus(boolean isEnabled) { Settings.Global.putInt(resolver, Settings.Global.NSD_ON, isEnabled ? 1 : 0); } }; } } } tests/net/java/android/net/nsd/NsdServiceTest.java 0 → 100644 +93 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 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.server; import static org.mockito.Mockito.when; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.test.TestLooper; import android.content.Context; import android.content.ContentResolver; import android.net.nsd.NsdManager; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; // TODOs: // - test daemon connection // - test client disconnects // - test client can send requests and receive replies // - test NSD_ON ENABLE/DISABLED listening @RunWith(AndroidJUnit4.class) @SmallTest public class NsdServiceTest { @Mock Context mContext; @Mock ContentResolver mResolver; @Mock NsdService.NsdSettings mSettings; TestLooper mLooper; TestHandler mHandler; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); mLooper = new TestLooper(); mHandler = new TestHandler(mLooper.getLooper()); when(mContext.getContentResolver()).thenReturn(mResolver); } @Test public void testClientsCanConnect() { NsdService service = makeService(); NsdManager client1 = connectClient(service); NsdManager client2 = connectClient(service); // TODO: disconnect client1 // TODO: disconnect client2 } NsdService makeService() { return new NsdService(mContext, mSettings, mHandler); } NsdManager connectClient(NsdService service) { mLooper.startAutoDispatch(); NsdManager client = new NsdManager(mContext, service); mLooper.stopAutoDispatch(); return client; } public static class TestHandler extends Handler { public Message lastMessage; TestHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { lastMessage = obtainMessage(); lastMessage.copyFrom(msg); } } } Loading
services/core/java/com/android/server/NsdService.java +45 −15 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ import android.net.nsd.DnsSdTxtRecord; import android.net.nsd.INsdManager; import android.net.nsd.NsdManager; import android.os.Binder; import android.os.HandlerThread; import android.os.Handler; import android.os.Message; import android.os.Messenger; import android.os.UserHandle; Loading @@ -40,6 +42,7 @@ import java.net.InetAddress; import java.util.HashMap; import java.util.concurrent.CountDownLatch; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.AsyncChannel; import com.android.internal.util.Protocol; import com.android.internal.util.State; Loading @@ -59,7 +62,7 @@ public class NsdService extends INsdManager.Stub { private static final boolean DBG = true; private final Context mContext; private final ContentResolver mContentResolver; private final NsdSettings mNsdSettings; private final NsdStateMachine mNsdStateMachine; private final NativeDaemonConnector mNativeConnector; private final CountDownLatch mNativeDaemonConnected = new CountDownLatch(1); Loading Loading @@ -108,8 +111,8 @@ public class NsdService extends INsdManager.Stub { false, contentObserver); } NsdStateMachine(String name) { super(name); NsdStateMachine(String name, Handler handler) { super(name, handler); addState(mDefaultState); addState(mDisabledState, mDefaultState); addState(mEnabledState, mDefaultState); Loading Loading @@ -541,14 +544,15 @@ public class NsdService extends INsdManager.Stub { return sb.toString(); } private NsdService(Context context) { mContext = context; mContentResolver = context.getContentResolver(); @VisibleForTesting NsdService(Context ctx, NsdSettings settings, Handler handler) { mContext = ctx; mNsdSettings = settings; mNativeConnector = new NativeDaemonConnector(new NativeCallbackReceiver(), "mdns", 10, MDNS_TAG, 25, null); NativeCallbackReceiver callback = new NativeCallbackReceiver(); mNativeConnector = new NativeDaemonConnector(callback, "mdns", 10, MDNS_TAG, 25, null); mNsdStateMachine = new NsdStateMachine(TAG); mNsdStateMachine = new NsdStateMachine(TAG, handler); mNsdStateMachine.start(); Thread th = new Thread(mNativeConnector, MDNS_TAG); Loading @@ -556,21 +560,24 @@ public class NsdService extends INsdManager.Stub { } public static NsdService create(Context context) throws InterruptedException { NsdService service = new NsdService(context); NsdSettings settings = NsdSettings.makeDefault(context); HandlerThread thread = new HandlerThread(TAG); thread.start(); Handler handler = new Handler(thread.getLooper()); NsdService service = new NsdService(context, settings, handler); service.mNativeDaemonConnected.await(); return service; } public Messenger getMessenger() { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INTERNET, "NsdService"); 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); mNsdSettings.putEnabledStatus(enable); if (enable) { mNsdStateMachine.sendMessage(NsdManager.ENABLE); } else { Loading @@ -590,8 +597,10 @@ public class NsdService extends INsdManager.Stub { } 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); boolean ret = mNsdSettings.isEnabled(); if (DBG) { Slog.d(TAG, "Network service discovery is " + (ret ? "enabled" : "disabled")); } return ret; } Loading Loading @@ -927,4 +936,25 @@ public class NsdService extends INsdManager.Stub { return -1; } } @VisibleForTesting public interface NsdSettings { boolean isEnabled(); void putEnabledStatus(boolean isEnabled); static NsdSettings makeDefault(Context context) { ContentResolver resolver = context.getContentResolver(); return new NsdSettings() { @Override public boolean isEnabled() { return Settings.Global.getInt(resolver, Settings.Global.NSD_ON, 1) == 1; } @Override public void putEnabledStatus(boolean isEnabled) { Settings.Global.putInt(resolver, Settings.Global.NSD_ON, isEnabled ? 1 : 0); } }; } } }
tests/net/java/android/net/nsd/NsdServiceTest.java 0 → 100644 +93 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 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.server; import static org.mockito.Mockito.when; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.test.TestLooper; import android.content.Context; import android.content.ContentResolver; import android.net.nsd.NsdManager; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; // TODOs: // - test daemon connection // - test client disconnects // - test client can send requests and receive replies // - test NSD_ON ENABLE/DISABLED listening @RunWith(AndroidJUnit4.class) @SmallTest public class NsdServiceTest { @Mock Context mContext; @Mock ContentResolver mResolver; @Mock NsdService.NsdSettings mSettings; TestLooper mLooper; TestHandler mHandler; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); mLooper = new TestLooper(); mHandler = new TestHandler(mLooper.getLooper()); when(mContext.getContentResolver()).thenReturn(mResolver); } @Test public void testClientsCanConnect() { NsdService service = makeService(); NsdManager client1 = connectClient(service); NsdManager client2 = connectClient(service); // TODO: disconnect client1 // TODO: disconnect client2 } NsdService makeService() { return new NsdService(mContext, mSettings, mHandler); } NsdManager connectClient(NsdService service) { mLooper.startAutoDispatch(); NsdManager client = new NsdManager(mContext, service); mLooper.stopAutoDispatch(); return client; } public static class TestHandler extends Handler { public Message lastMessage; TestHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { lastMessage = obtainMessage(); lastMessage.copyFrom(msg); } } }