Create the MdnsDiscoveryManager
Create the MdnsDiscoveryManager for mdns discovery and resolution if the feature is enable. Bug: 254166302 Test: atest FrameworksNetTests CtsNetTestCases Change-Id: I4d7591b50cb06f0efcc0dde9834b775c513cceff
This commit is contained in:
@@ -18,7 +18,9 @@ package com.android.server;
|
|||||||
|
|
||||||
import static android.net.ConnectivityManager.NETID_UNSET;
|
import static android.net.ConnectivityManager.NETID_UNSET;
|
||||||
import static android.net.nsd.NsdManager.MDNS_SERVICE_EVENT;
|
import static android.net.nsd.NsdManager.MDNS_SERVICE_EVENT;
|
||||||
|
import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY;
|
||||||
|
|
||||||
|
import android.annotation.Nullable;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
@@ -39,6 +41,7 @@ import android.net.nsd.NsdServiceInfo;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
@@ -50,7 +53,13 @@ import android.util.SparseIntArray;
|
|||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.util.State;
|
import com.android.internal.util.State;
|
||||||
import com.android.internal.util.StateMachine;
|
import com.android.internal.util.StateMachine;
|
||||||
|
import com.android.net.module.util.DeviceConfigUtils;
|
||||||
import com.android.net.module.util.PermissionUtils;
|
import com.android.net.module.util.PermissionUtils;
|
||||||
|
import com.android.server.connectivity.mdns.ExecutorProvider;
|
||||||
|
import com.android.server.connectivity.mdns.MdnsDiscoveryManager;
|
||||||
|
import com.android.server.connectivity.mdns.MdnsMultinetworkSocketClient;
|
||||||
|
import com.android.server.connectivity.mdns.MdnsSocketClientBase;
|
||||||
|
import com.android.server.connectivity.mdns.MdnsSocketProvider;
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
@@ -69,6 +78,7 @@ import java.util.HashMap;
|
|||||||
public class NsdService extends INsdManager.Stub {
|
public class NsdService extends INsdManager.Stub {
|
||||||
private static final String TAG = "NsdService";
|
private static final String TAG = "NsdService";
|
||||||
private static final String MDNS_TAG = "mDnsConnector";
|
private static final String MDNS_TAG = "mDnsConnector";
|
||||||
|
private static final String MDNS_DISCOVERY_MANAGER_VERSION = "mdns_discovery_manager_version";
|
||||||
|
|
||||||
private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
|
private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
|
||||||
private static final long CLEANUP_DELAY_MS = 10000;
|
private static final long CLEANUP_DELAY_MS = 10000;
|
||||||
@@ -78,6 +88,12 @@ public class NsdService extends INsdManager.Stub {
|
|||||||
private final NsdStateMachine mNsdStateMachine;
|
private final NsdStateMachine mNsdStateMachine;
|
||||||
private final MDnsManager mMDnsManager;
|
private final MDnsManager mMDnsManager;
|
||||||
private final MDnsEventCallback mMDnsEventCallback;
|
private final MDnsEventCallback mMDnsEventCallback;
|
||||||
|
@Nullable
|
||||||
|
private final MdnsMultinetworkSocketClient mMdnsSocketClient;
|
||||||
|
@Nullable
|
||||||
|
private final MdnsDiscoveryManager mMdnsDiscoveryManager;
|
||||||
|
@Nullable
|
||||||
|
private final MdnsSocketProvider mMdnsSocketProvider;
|
||||||
// WARNING : Accessing this value in any thread is not safe, it must only be changed in the
|
// WARNING : Accessing this value in any thread is not safe, it must only be changed in the
|
||||||
// state machine thread. If change this outside state machine, it will need to introduce
|
// state machine thread. If change this outside state machine, it will need to introduce
|
||||||
// synchronization.
|
// synchronization.
|
||||||
@@ -650,12 +666,61 @@ public class NsdService extends INsdManager.Stub {
|
|||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
NsdService(Context ctx, Handler handler, long cleanupDelayMs) {
|
NsdService(Context ctx, Handler handler, long cleanupDelayMs) {
|
||||||
|
this(ctx, handler, cleanupDelayMs, new Dependencies());
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
NsdService(Context ctx, Handler handler, long cleanupDelayMs, Dependencies deps) {
|
||||||
mCleanupDelayMs = cleanupDelayMs;
|
mCleanupDelayMs = cleanupDelayMs;
|
||||||
mContext = ctx;
|
mContext = ctx;
|
||||||
mNsdStateMachine = new NsdStateMachine(TAG, handler);
|
mNsdStateMachine = new NsdStateMachine(TAG, handler);
|
||||||
mNsdStateMachine.start();
|
mNsdStateMachine.start();
|
||||||
mMDnsManager = ctx.getSystemService(MDnsManager.class);
|
mMDnsManager = ctx.getSystemService(MDnsManager.class);
|
||||||
mMDnsEventCallback = new MDnsEventCallback(mNsdStateMachine);
|
mMDnsEventCallback = new MDnsEventCallback(mNsdStateMachine);
|
||||||
|
if (deps.isMdnsDiscoveryManagerEnabled(ctx)) {
|
||||||
|
mMdnsSocketProvider = deps.makeMdnsSocketProvider(ctx, handler.getLooper());
|
||||||
|
mMdnsSocketClient =
|
||||||
|
new MdnsMultinetworkSocketClient(handler.getLooper(), mMdnsSocketProvider);
|
||||||
|
mMdnsDiscoveryManager =
|
||||||
|
deps.makeMdnsDiscoveryManager(new ExecutorProvider(), mMdnsSocketClient);
|
||||||
|
handler.post(() -> mMdnsSocketClient.setCallback(mMdnsDiscoveryManager));
|
||||||
|
} else {
|
||||||
|
mMdnsSocketProvider = null;
|
||||||
|
mMdnsSocketClient = null;
|
||||||
|
mMdnsDiscoveryManager = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies of NsdService, for injection in tests.
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
public static class Dependencies {
|
||||||
|
/**
|
||||||
|
* Check whether or not MdnsDiscoveryManager feature is enabled.
|
||||||
|
*
|
||||||
|
* @param context The global context information about an app environment.
|
||||||
|
* @return true if MdnsDiscoveryManager feature is enabled.
|
||||||
|
*/
|
||||||
|
public boolean isMdnsDiscoveryManagerEnabled(Context context) {
|
||||||
|
return DeviceConfigUtils.isFeatureEnabled(context, NAMESPACE_CONNECTIVITY,
|
||||||
|
MDNS_DISCOVERY_MANAGER_VERSION, false /* defaultEnabled */);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see MdnsDiscoveryManager
|
||||||
|
*/
|
||||||
|
public MdnsDiscoveryManager makeMdnsDiscoveryManager(
|
||||||
|
ExecutorProvider executorProvider, MdnsSocketClientBase socketClient) {
|
||||||
|
return new MdnsDiscoveryManager(executorProvider, socketClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see MdnsSocketProvider
|
||||||
|
*/
|
||||||
|
public MdnsSocketProvider makeMdnsSocketProvider(Context context, Looper looper) {
|
||||||
|
return new MdnsSocketProvider(context, looper);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static NsdService create(Context context) {
|
public static NsdService create(Context context) {
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ package com.android.server;
|
|||||||
|
|
||||||
import static android.net.nsd.NsdManager.FAILURE_INTERNAL_ERROR;
|
import static android.net.nsd.NsdManager.FAILURE_INTERNAL_ERROR;
|
||||||
|
|
||||||
|
import static com.android.testutils.ContextUtils.mockService;
|
||||||
|
|
||||||
import static libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
|
import static libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
|
||||||
import static libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
|
import static libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
|
||||||
|
|
||||||
@@ -67,6 +69,7 @@ import android.os.Message;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
|
import com.android.server.NsdService.Dependencies;
|
||||||
import com.android.testutils.DevSdkIgnoreRule;
|
import com.android.testutils.DevSdkIgnoreRule;
|
||||||
import com.android.testutils.DevSdkIgnoreRunner;
|
import com.android.testutils.DevSdkIgnoreRunner;
|
||||||
import com.android.testutils.HandlerUtils;
|
import com.android.testutils.HandlerUtils;
|
||||||
@@ -112,6 +115,7 @@ public class NsdServiceTest {
|
|||||||
@Mock Context mContext;
|
@Mock Context mContext;
|
||||||
@Mock ContentResolver mResolver;
|
@Mock ContentResolver mResolver;
|
||||||
@Mock MDnsManager mMockMDnsM;
|
@Mock MDnsManager mMockMDnsM;
|
||||||
|
@Mock Dependencies mDeps;
|
||||||
HandlerThread mThread;
|
HandlerThread mThread;
|
||||||
TestHandler mHandler;
|
TestHandler mHandler;
|
||||||
NsdService mService;
|
NsdService mService;
|
||||||
@@ -133,9 +137,7 @@ public class NsdServiceTest {
|
|||||||
mThread.start();
|
mThread.start();
|
||||||
mHandler = new TestHandler(mThread.getLooper());
|
mHandler = new TestHandler(mThread.getLooper());
|
||||||
when(mContext.getContentResolver()).thenReturn(mResolver);
|
when(mContext.getContentResolver()).thenReturn(mResolver);
|
||||||
doReturn(MDnsManager.MDNS_SERVICE).when(mContext)
|
mockService(mContext, MDnsManager.class, MDnsManager.MDNS_SERVICE, mMockMDnsM);
|
||||||
.getSystemServiceName(MDnsManager.class);
|
|
||||||
doReturn(mMockMDnsM).when(mContext).getSystemService(MDnsManager.MDNS_SERVICE);
|
|
||||||
if (mContext.getSystemService(MDnsManager.class) == null) {
|
if (mContext.getSystemService(MDnsManager.class) == null) {
|
||||||
// Test is using mockito-extended
|
// Test is using mockito-extended
|
||||||
doCallRealMethod().when(mContext).getSystemService(MDnsManager.class);
|
doCallRealMethod().when(mContext).getSystemService(MDnsManager.class);
|
||||||
@@ -146,6 +148,7 @@ public class NsdServiceTest {
|
|||||||
doReturn(true).when(mMockMDnsM).discover(anyInt(), anyString(), anyInt());
|
doReturn(true).when(mMockMDnsM).discover(anyInt(), anyString(), anyInt());
|
||||||
doReturn(true).when(mMockMDnsM).resolve(
|
doReturn(true).when(mMockMDnsM).resolve(
|
||||||
anyInt(), anyString(), anyString(), anyString(), anyInt());
|
anyInt(), anyString(), anyString(), anyString(), anyInt());
|
||||||
|
doReturn(false).when(mDeps).isMdnsDiscoveryManagerEnabled(any(Context.class));
|
||||||
|
|
||||||
mService = makeService();
|
mService = makeService();
|
||||||
}
|
}
|
||||||
@@ -555,12 +558,27 @@ public class NsdServiceTest {
|
|||||||
anyInt()/* interfaceIdx */);
|
anyInt()/* interfaceIdx */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMdnsDiscoveryManagerFeature() {
|
||||||
|
// Create NsdService w/o feature enabled.
|
||||||
|
connectClient(mService);
|
||||||
|
verify(mDeps, never()).makeMdnsDiscoveryManager(any(), any());
|
||||||
|
verify(mDeps, never()).makeMdnsSocketProvider(any(), any());
|
||||||
|
|
||||||
|
// Create NsdService again w/ feature enabled.
|
||||||
|
doReturn(true).when(mDeps).isMdnsDiscoveryManagerEnabled(any(Context.class));
|
||||||
|
makeService();
|
||||||
|
verify(mDeps).makeMdnsDiscoveryManager(any(), any());
|
||||||
|
verify(mDeps).makeMdnsSocketProvider(any(), any());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void waitForIdle() {
|
private void waitForIdle() {
|
||||||
HandlerUtils.waitForIdle(mHandler, TIMEOUT_MS);
|
HandlerUtils.waitForIdle(mHandler, TIMEOUT_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
NsdService makeService() {
|
NsdService makeService() {
|
||||||
final NsdService service = new NsdService(mContext, mHandler, CLEANUP_DELAY_MS) {
|
final NsdService service = new NsdService(mContext, mHandler, CLEANUP_DELAY_MS, mDeps) {
|
||||||
@Override
|
@Override
|
||||||
public INsdServiceConnector connect(INsdManagerCallback baseCb) {
|
public INsdServiceConnector connect(INsdManagerCallback baseCb) {
|
||||||
// Wrap the callback in a transparent mock, to mock asBinder returning a
|
// Wrap the callback in a transparent mock, to mock asBinder returning a
|
||||||
|
|||||||
Reference in New Issue
Block a user