Merge "[Thread] add the "vgh" TXT entry" into main
This commit is contained in:
commit
7ff092e3d1
7 changed files with 80 additions and 95 deletions
|
|
@ -53,4 +53,10 @@
|
||||||
UTF-8 bytes.
|
UTF-8 bytes.
|
||||||
-->
|
-->
|
||||||
<string translatable="false" name="config_thread_model_name">Thread Border Router</string>
|
<string translatable="false" name="config_thread_model_name">Thread Border Router</string>
|
||||||
|
|
||||||
|
<!-- Whether the Thread network will be managed by the Google Home ecosystem. When this value
|
||||||
|
is set, a TXT entry "vgh=0" or "vgh=1" will be added to the "_mehscop._udp" mDNS service
|
||||||
|
respectively (The TXT value is a string).
|
||||||
|
-->
|
||||||
|
<bool name="config_thread_managed_by_google_home">false</bool>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,6 @@ import com.android.server.thread.openthread.INsdStatusReceiver;
|
||||||
import java.net.Inet6Address;
|
import java.net.Inet6Address;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -615,9 +614,8 @@ public final class NsdPublisher extends INsdPublisher.Stub {
|
||||||
}
|
}
|
||||||
List<DnsTxtAttribute> txtList = new ArrayList<>();
|
List<DnsTxtAttribute> txtList = new ArrayList<>();
|
||||||
for (Map.Entry<String, byte[]> entry : serviceInfo.getAttributes().entrySet()) {
|
for (Map.Entry<String, byte[]> entry : serviceInfo.getAttributes().entrySet()) {
|
||||||
DnsTxtAttribute attribute = new DnsTxtAttribute();
|
DnsTxtAttribute attribute =
|
||||||
attribute.name = entry.getKey();
|
new DnsTxtAttribute(entry.getKey(), entry.getValue().clone());
|
||||||
attribute.value = Arrays.copyOf(entry.getValue(), entry.getValue().length);
|
|
||||||
txtList.add(attribute);
|
txtList.add(attribute);
|
||||||
}
|
}
|
||||||
// TODO: b/329018320 - Use the serviceInfo.getExpirationTime to derive TTL.
|
// TODO: b/329018320 - Use the serviceInfo.getExpirationTime to derive TTL.
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,8 @@ import static com.android.server.thread.openthread.IOtDaemon.OT_STATE_DISABLING;
|
||||||
import static com.android.server.thread.openthread.IOtDaemon.OT_STATE_ENABLED;
|
import static com.android.server.thread.openthread.IOtDaemon.OT_STATE_ENABLED;
|
||||||
import static com.android.server.thread.openthread.IOtDaemon.TUN_IF_NAME;
|
import static com.android.server.thread.openthread.IOtDaemon.TUN_IF_NAME;
|
||||||
|
|
||||||
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
||||||
import android.Manifest.permission;
|
import android.Manifest.permission;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
|
|
@ -117,6 +119,7 @@ import com.android.server.ServiceManagerWrapper;
|
||||||
import com.android.server.connectivity.ConnectivityResources;
|
import com.android.server.connectivity.ConnectivityResources;
|
||||||
import com.android.server.thread.openthread.BackboneRouterState;
|
import com.android.server.thread.openthread.BackboneRouterState;
|
||||||
import com.android.server.thread.openthread.BorderRouterConfigurationParcel;
|
import com.android.server.thread.openthread.BorderRouterConfigurationParcel;
|
||||||
|
import com.android.server.thread.openthread.DnsTxtAttribute;
|
||||||
import com.android.server.thread.openthread.IChannelMasksReceiver;
|
import com.android.server.thread.openthread.IChannelMasksReceiver;
|
||||||
import com.android.server.thread.openthread.IOtDaemon;
|
import com.android.server.thread.openthread.IOtDaemon;
|
||||||
import com.android.server.thread.openthread.IOtDaemonCallback;
|
import com.android.server.thread.openthread.IOtDaemonCallback;
|
||||||
|
|
@ -130,7 +133,6 @@ import libcore.util.HexEncoding;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.Inet6Address;
|
import java.net.Inet6Address;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.time.Clock;
|
import java.time.Clock;
|
||||||
import java.time.DateTimeException;
|
import java.time.DateTimeException;
|
||||||
|
|
@ -338,9 +340,11 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub
|
||||||
final String modelName = resources.getString(R.string.config_thread_model_name);
|
final String modelName = resources.getString(R.string.config_thread_model_name);
|
||||||
final String vendorName = resources.getString(R.string.config_thread_vendor_name);
|
final String vendorName = resources.getString(R.string.config_thread_vendor_name);
|
||||||
final String vendorOui = resources.getString(R.string.config_thread_vendor_oui);
|
final String vendorOui = resources.getString(R.string.config_thread_vendor_oui);
|
||||||
|
final boolean managedByGoogle =
|
||||||
|
resources.getBoolean(R.bool.config_thread_managed_by_google_home);
|
||||||
|
|
||||||
if (!modelName.isEmpty()) {
|
if (!modelName.isEmpty()) {
|
||||||
if (modelName.getBytes(StandardCharsets.UTF_8).length > MAX_MODEL_NAME_UTF8_BYTES) {
|
if (modelName.getBytes(UTF_8).length > MAX_MODEL_NAME_UTF8_BYTES) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Model name is longer than "
|
"Model name is longer than "
|
||||||
+ MAX_MODEL_NAME_UTF8_BYTES
|
+ MAX_MODEL_NAME_UTF8_BYTES
|
||||||
|
|
@ -350,7 +354,7 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vendorName.isEmpty()) {
|
if (!vendorName.isEmpty()) {
|
||||||
if (vendorName.getBytes(StandardCharsets.UTF_8).length > MAX_VENDOR_NAME_UTF8_BYTES) {
|
if (vendorName.getBytes(UTF_8).length > MAX_VENDOR_NAME_UTF8_BYTES) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Vendor name is longer than "
|
"Vendor name is longer than "
|
||||||
+ MAX_VENDOR_NAME_UTF8_BYTES
|
+ MAX_VENDOR_NAME_UTF8_BYTES
|
||||||
|
|
@ -367,9 +371,21 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub
|
||||||
meshcopTxts.modelName = modelName;
|
meshcopTxts.modelName = modelName;
|
||||||
meshcopTxts.vendorName = vendorName;
|
meshcopTxts.vendorName = vendorName;
|
||||||
meshcopTxts.vendorOui = HexEncoding.decode(vendorOui.replace("-", "").replace(":", ""));
|
meshcopTxts.vendorOui = HexEncoding.decode(vendorOui.replace("-", "").replace(":", ""));
|
||||||
|
meshcopTxts.nonStandardTxtEntries = List.of(makeManagedByGoogleTxtAttr(managedByGoogle));
|
||||||
|
|
||||||
return meshcopTxts;
|
return meshcopTxts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a DNS-SD TXT entry for indicating whether Thread on this device is managed by Google.
|
||||||
|
*
|
||||||
|
* @return TXT entry "vgh=1" if {@code managedByGoogle} is {@code true}; otherwise, "vgh=0"
|
||||||
|
*/
|
||||||
|
private static DnsTxtAttribute makeManagedByGoogleTxtAttr(boolean managedByGoogle) {
|
||||||
|
final byte[] value = (managedByGoogle ? "1" : "0").getBytes(UTF_8);
|
||||||
|
return new DnsTxtAttribute("vgh", value);
|
||||||
|
}
|
||||||
|
|
||||||
private void onOtDaemonDied() {
|
private void onOtDaemonDied() {
|
||||||
checkOnHandlerThread();
|
checkOnHandlerThread();
|
||||||
Log.w(TAG, "OT daemon is dead, clean up...");
|
Log.w(TAG, "OT daemon is dead, clean up...");
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,6 @@ import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
|
||||||
|
|
||||||
import static org.junit.Assert.assertThrows;
|
import static org.junit.Assert.assertThrows;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
@ -859,6 +858,7 @@ public class ThreadNetworkControllerTest {
|
||||||
assertThat(txtMap.get("rv")).isNotNull();
|
assertThat(txtMap.get("rv")).isNotNull();
|
||||||
assertThat(txtMap.get("tv")).isNotNull();
|
assertThat(txtMap.get("tv")).isNotNull();
|
||||||
assertThat(txtMap.get("sb")).isNotNull();
|
assertThat(txtMap.get("sb")).isNotNull();
|
||||||
|
assertThat(new String(txtMap.get("vgh"))).isIn(List.of("0", "1"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -885,6 +885,7 @@ public class ThreadNetworkControllerTest {
|
||||||
assertThat(txtMap.get("tv")).isNotNull();
|
assertThat(txtMap.get("tv")).isNotNull();
|
||||||
assertThat(txtMap.get("sb")).isNotNull();
|
assertThat(txtMap.get("sb")).isNotNull();
|
||||||
assertThat(txtMap.get("id").length).isEqualTo(16);
|
assertThat(txtMap.get("id").length).isEqualTo(16);
|
||||||
|
assertThat(new String(txtMap.get("vgh"))).isIn(List.of("0", "1"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,9 @@ package android.net.thread.utils;
|
||||||
|
|
||||||
import static android.net.thread.utils.IntegrationTestUtils.SERVICE_DISCOVERY_TIMEOUT;
|
import static android.net.thread.utils.IntegrationTestUtils.SERVICE_DISCOVERY_TIMEOUT;
|
||||||
import static android.net.thread.utils.IntegrationTestUtils.waitFor;
|
import static android.net.thread.utils.IntegrationTestUtils.waitFor;
|
||||||
|
|
||||||
import static com.google.common.io.BaseEncoding.base16;
|
import static com.google.common.io.BaseEncoding.base16;
|
||||||
|
|
||||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
|
|
||||||
import android.net.InetAddresses;
|
import android.net.InetAddresses;
|
||||||
|
|
@ -26,7 +28,9 @@ import android.net.nsd.NsdServiceInfo;
|
||||||
import android.net.thread.ActiveOperationalDataset;
|
import android.net.thread.ActiveOperationalDataset;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
|
|
||||||
import com.google.errorprone.annotations.FormatMethod;
|
import com.google.errorprone.annotations.FormatMethod;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
|
||||||
|
|
@ -22,14 +22,15 @@ import static android.net.nsd.NsdManager.PROTOCOL_DNS_SD;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.ArgumentMatchers.argThat;
|
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.doThrow;
|
import static org.mockito.Mockito.doThrow;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.hamcrest.MockitoHamcrest.argThat;
|
||||||
|
|
||||||
import android.net.DnsResolver;
|
import android.net.DnsResolver;
|
||||||
import android.net.InetAddresses;
|
import android.net.InetAddresses;
|
||||||
|
|
@ -50,21 +51,23 @@ import com.android.server.thread.openthread.INsdStatusReceiver;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.ArgumentMatcher;
|
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
/** Unit tests for {@link NsdPublisher}. */
|
/** Unit tests for {@link NsdPublisher}. */
|
||||||
public final class NsdPublisherTest {
|
public final class NsdPublisherTest {
|
||||||
|
private static final DnsTxtAttribute TEST_TXT_ENTRY_1 =
|
||||||
|
new DnsTxtAttribute("key1", new byte[] {0x01, 0x02});
|
||||||
|
private static final DnsTxtAttribute TEST_TXT_ENTRY_2 =
|
||||||
|
new DnsTxtAttribute("key2", new byte[] {0x03});
|
||||||
|
|
||||||
@Mock private NsdManager mMockNsdManager;
|
@Mock private NsdManager mMockNsdManager;
|
||||||
@Mock private DnsResolver mMockDnsResolver;
|
@Mock private DnsResolver mMockDnsResolver;
|
||||||
|
|
||||||
|
|
@ -87,19 +90,15 @@ public final class NsdPublisherTest {
|
||||||
public void registerService_nsdManagerSucceeds_serviceRegistrationSucceeds() throws Exception {
|
public void registerService_nsdManagerSucceeds_serviceRegistrationSucceeds() throws Exception {
|
||||||
prepareTest();
|
prepareTest();
|
||||||
|
|
||||||
DnsTxtAttribute txt1 = makeTxtAttribute("key1", List.of(0x01, 0x02));
|
|
||||||
DnsTxtAttribute txt2 = makeTxtAttribute("key2", List.of(0x03));
|
|
||||||
|
|
||||||
mNsdPublisher.registerService(
|
mNsdPublisher.registerService(
|
||||||
null,
|
null,
|
||||||
"MyService",
|
"MyService",
|
||||||
"_test._tcp",
|
"_test._tcp",
|
||||||
List.of("_subtype1", "_subtype2"),
|
List.of("_subtype1", "_subtype2"),
|
||||||
12345,
|
12345,
|
||||||
List.of(txt1, txt2),
|
List.of(TEST_TXT_ENTRY_1, TEST_TXT_ENTRY_2),
|
||||||
mRegistrationReceiver,
|
mRegistrationReceiver,
|
||||||
16 /* listenerId */);
|
16 /* listenerId */);
|
||||||
|
|
||||||
mTestLooper.dispatchAll();
|
mTestLooper.dispatchAll();
|
||||||
|
|
||||||
ArgumentCaptor<NsdServiceInfo> actualServiceInfoCaptor =
|
ArgumentCaptor<NsdServiceInfo> actualServiceInfoCaptor =
|
||||||
|
|
@ -126,11 +125,10 @@ public final class NsdPublisherTest {
|
||||||
assertThat(actualServiceInfo.getSubtypes()).isEqualTo(Set.of("_subtype1", "_subtype2"));
|
assertThat(actualServiceInfo.getSubtypes()).isEqualTo(Set.of("_subtype1", "_subtype2"));
|
||||||
assertThat(actualServiceInfo.getPort()).isEqualTo(12345);
|
assertThat(actualServiceInfo.getPort()).isEqualTo(12345);
|
||||||
assertThat(actualServiceInfo.getAttributes().size()).isEqualTo(2);
|
assertThat(actualServiceInfo.getAttributes().size()).isEqualTo(2);
|
||||||
assertThat(actualServiceInfo.getAttributes().get("key1"))
|
assertThat(actualServiceInfo.getAttributes().get(TEST_TXT_ENTRY_1.name))
|
||||||
.isEqualTo(new byte[] {(byte) 0x01, (byte) 0x02});
|
.isEqualTo(TEST_TXT_ENTRY_1.value);
|
||||||
assertThat(actualServiceInfo.getAttributes().get("key2"))
|
assertThat(actualServiceInfo.getAttributes().get(TEST_TXT_ENTRY_2.name))
|
||||||
.isEqualTo(new byte[] {(byte) 0x03});
|
.isEqualTo(TEST_TXT_ENTRY_2.value);
|
||||||
|
|
||||||
verify(mRegistrationReceiver, times(1)).onSuccess();
|
verify(mRegistrationReceiver, times(1)).onSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -138,19 +136,15 @@ public final class NsdPublisherTest {
|
||||||
public void registerService_nsdManagerFails_serviceRegistrationFails() throws Exception {
|
public void registerService_nsdManagerFails_serviceRegistrationFails() throws Exception {
|
||||||
prepareTest();
|
prepareTest();
|
||||||
|
|
||||||
DnsTxtAttribute txt1 = makeTxtAttribute("key1", List.of(0x01, 0x02));
|
|
||||||
DnsTxtAttribute txt2 = makeTxtAttribute("key2", List.of(0x03));
|
|
||||||
|
|
||||||
mNsdPublisher.registerService(
|
mNsdPublisher.registerService(
|
||||||
null,
|
null,
|
||||||
"MyService",
|
"MyService",
|
||||||
"_test._tcp",
|
"_test._tcp",
|
||||||
List.of("_subtype1", "_subtype2"),
|
List.of("_subtype1", "_subtype2"),
|
||||||
12345,
|
12345,
|
||||||
List.of(txt1, txt2),
|
List.of(TEST_TXT_ENTRY_1, TEST_TXT_ENTRY_2),
|
||||||
mRegistrationReceiver,
|
mRegistrationReceiver,
|
||||||
16 /* listenerId */);
|
16 /* listenerId */);
|
||||||
|
|
||||||
mTestLooper.dispatchAll();
|
mTestLooper.dispatchAll();
|
||||||
|
|
||||||
ArgumentCaptor<NsdServiceInfo> actualServiceInfoCaptor =
|
ArgumentCaptor<NsdServiceInfo> actualServiceInfoCaptor =
|
||||||
|
|
@ -177,21 +171,16 @@ public final class NsdPublisherTest {
|
||||||
assertThat(actualServiceInfo.getSubtypes()).isEqualTo(Set.of("_subtype1", "_subtype2"));
|
assertThat(actualServiceInfo.getSubtypes()).isEqualTo(Set.of("_subtype1", "_subtype2"));
|
||||||
assertThat(actualServiceInfo.getPort()).isEqualTo(12345);
|
assertThat(actualServiceInfo.getPort()).isEqualTo(12345);
|
||||||
assertThat(actualServiceInfo.getAttributes().size()).isEqualTo(2);
|
assertThat(actualServiceInfo.getAttributes().size()).isEqualTo(2);
|
||||||
assertThat(actualServiceInfo.getAttributes().get("key1"))
|
assertThat(actualServiceInfo.getAttributes().get(TEST_TXT_ENTRY_1.name))
|
||||||
.isEqualTo(new byte[] {(byte) 0x01, (byte) 0x02});
|
.isEqualTo(TEST_TXT_ENTRY_1.value);
|
||||||
assertThat(actualServiceInfo.getAttributes().get("key2"))
|
assertThat(actualServiceInfo.getAttributes().get(TEST_TXT_ENTRY_2.name))
|
||||||
.isEqualTo(new byte[] {(byte) 0x03});
|
.isEqualTo(TEST_TXT_ENTRY_2.value);
|
||||||
|
|
||||||
verify(mRegistrationReceiver, times(1)).onError(FAILURE_INTERNAL_ERROR);
|
verify(mRegistrationReceiver, times(1)).onError(FAILURE_INTERNAL_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void registerService_nsdManagerThrows_serviceRegistrationFails() throws Exception {
|
public void registerService_nsdManagerThrows_serviceRegistrationFails() throws Exception {
|
||||||
prepareTest();
|
prepareTest();
|
||||||
|
|
||||||
DnsTxtAttribute txt1 = makeTxtAttribute("key1", List.of(0x01, 0x02));
|
|
||||||
DnsTxtAttribute txt2 = makeTxtAttribute("key2", List.of(0x03));
|
|
||||||
|
|
||||||
doThrow(new IllegalArgumentException("NsdManager fails"))
|
doThrow(new IllegalArgumentException("NsdManager fails"))
|
||||||
.when(mMockNsdManager)
|
.when(mMockNsdManager)
|
||||||
.registerService(any(), anyInt(), any(Executor.class), any());
|
.registerService(any(), anyInt(), any(Executor.class), any());
|
||||||
|
|
@ -202,7 +191,7 @@ public final class NsdPublisherTest {
|
||||||
"_test._tcp",
|
"_test._tcp",
|
||||||
List.of("_subtype1", "_subtype2"),
|
List.of("_subtype1", "_subtype2"),
|
||||||
12345,
|
12345,
|
||||||
List.of(txt1, txt2),
|
List.of(TEST_TXT_ENTRY_1, TEST_TXT_ENTRY_2),
|
||||||
mRegistrationReceiver,
|
mRegistrationReceiver,
|
||||||
16 /* listenerId */);
|
16 /* listenerId */);
|
||||||
mTestLooper.dispatchAll();
|
mTestLooper.dispatchAll();
|
||||||
|
|
@ -215,16 +204,13 @@ public final class NsdPublisherTest {
|
||||||
throws Exception {
|
throws Exception {
|
||||||
prepareTest();
|
prepareTest();
|
||||||
|
|
||||||
DnsTxtAttribute txt1 = makeTxtAttribute("key1", List.of(0x01, 0x02));
|
|
||||||
DnsTxtAttribute txt2 = makeTxtAttribute("key2", List.of(0x03));
|
|
||||||
|
|
||||||
mNsdPublisher.registerService(
|
mNsdPublisher.registerService(
|
||||||
null,
|
null,
|
||||||
"MyService",
|
"MyService",
|
||||||
"_test._tcp",
|
"_test._tcp",
|
||||||
List.of("_subtype1", "_subtype2"),
|
List.of("_subtype1", "_subtype2"),
|
||||||
12345,
|
12345,
|
||||||
List.of(txt1, txt2),
|
List.of(TEST_TXT_ENTRY_1, TEST_TXT_ENTRY_2),
|
||||||
mRegistrationReceiver,
|
mRegistrationReceiver,
|
||||||
16 /* listenerId */);
|
16 /* listenerId */);
|
||||||
|
|
||||||
|
|
@ -260,16 +246,13 @@ public final class NsdPublisherTest {
|
||||||
public void unregisterService_nsdManagerFails_serviceUnregistrationFails() throws Exception {
|
public void unregisterService_nsdManagerFails_serviceUnregistrationFails() throws Exception {
|
||||||
prepareTest();
|
prepareTest();
|
||||||
|
|
||||||
DnsTxtAttribute txt1 = makeTxtAttribute("key1", List.of(0x01, 0x02));
|
|
||||||
DnsTxtAttribute txt2 = makeTxtAttribute("key2", List.of(0x03));
|
|
||||||
|
|
||||||
mNsdPublisher.registerService(
|
mNsdPublisher.registerService(
|
||||||
null,
|
null,
|
||||||
"MyService",
|
"MyService",
|
||||||
"_test._tcp",
|
"_test._tcp",
|
||||||
List.of("_subtype1", "_subtype2"),
|
List.of("_subtype1", "_subtype2"),
|
||||||
12345,
|
12345,
|
||||||
List.of(txt1, txt2),
|
List.of(TEST_TXT_ENTRY_1, TEST_TXT_ENTRY_2),
|
||||||
mRegistrationReceiver,
|
mRegistrationReceiver,
|
||||||
16 /* listenerId */);
|
16 /* listenerId */);
|
||||||
|
|
||||||
|
|
@ -587,8 +570,8 @@ public final class NsdPublisherTest {
|
||||||
List.of(
|
List.of(
|
||||||
InetAddress.parseNumericAddress("2001::1"),
|
InetAddress.parseNumericAddress("2001::1"),
|
||||||
InetAddress.parseNumericAddress("2001::2")));
|
InetAddress.parseNumericAddress("2001::2")));
|
||||||
serviceInfo.setAttribute("key1", new byte[] {(byte) 0x01, (byte) 0x02});
|
serviceInfo.setAttribute(TEST_TXT_ENTRY_1.name, TEST_TXT_ENTRY_1.value);
|
||||||
serviceInfo.setAttribute("key2", new byte[] {(byte) 0x03});
|
serviceInfo.setAttribute(TEST_TXT_ENTRY_2.name, TEST_TXT_ENTRY_2.value);
|
||||||
serviceInfoCallbackArgumentCaptor.getValue().onServiceUpdated(serviceInfo);
|
serviceInfoCallbackArgumentCaptor.getValue().onServiceUpdated(serviceInfo);
|
||||||
mTestLooper.dispatchAll();
|
mTestLooper.dispatchAll();
|
||||||
|
|
||||||
|
|
@ -599,11 +582,8 @@ public final class NsdPublisherTest {
|
||||||
eq("_test._tcp"),
|
eq("_test._tcp"),
|
||||||
eq(12345),
|
eq(12345),
|
||||||
eq(List.of("2001::1", "2001::2")),
|
eq(List.of("2001::1", "2001::2")),
|
||||||
argThat(
|
(List<DnsTxtAttribute>)
|
||||||
new TxtMatcher(
|
argThat(containsInAnyOrder(TEST_TXT_ENTRY_1, TEST_TXT_ENTRY_2)),
|
||||||
List.of(
|
|
||||||
makeTxtAttribute("key1", List.of(0x01, 0x02)),
|
|
||||||
makeTxtAttribute("key2", List.of(0x03))))),
|
|
||||||
anyInt());
|
anyInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -725,10 +705,6 @@ public final class NsdPublisherTest {
|
||||||
@Test
|
@Test
|
||||||
public void reset_unregisterAll() {
|
public void reset_unregisterAll() {
|
||||||
prepareTest();
|
prepareTest();
|
||||||
|
|
||||||
DnsTxtAttribute txt1 = makeTxtAttribute("key1", List.of(0x01, 0x02));
|
|
||||||
DnsTxtAttribute txt2 = makeTxtAttribute("key2", List.of(0x03));
|
|
||||||
|
|
||||||
ArgumentCaptor<NsdServiceInfo> actualServiceInfoCaptor =
|
ArgumentCaptor<NsdServiceInfo> actualServiceInfoCaptor =
|
||||||
ArgumentCaptor.forClass(NsdServiceInfo.class);
|
ArgumentCaptor.forClass(NsdServiceInfo.class);
|
||||||
ArgumentCaptor<NsdManager.RegistrationListener> actualRegistrationListenerCaptor =
|
ArgumentCaptor<NsdManager.RegistrationListener> actualRegistrationListenerCaptor =
|
||||||
|
|
@ -740,7 +716,7 @@ public final class NsdPublisherTest {
|
||||||
"_test._tcp",
|
"_test._tcp",
|
||||||
List.of("_subtype1", "_subtype2"),
|
List.of("_subtype1", "_subtype2"),
|
||||||
12345,
|
12345,
|
||||||
List.of(txt1, txt2),
|
List.of(TEST_TXT_ENTRY_1, TEST_TXT_ENTRY_2),
|
||||||
mRegistrationReceiver,
|
mRegistrationReceiver,
|
||||||
16 /* listenerId */);
|
16 /* listenerId */);
|
||||||
mTestLooper.dispatchAll();
|
mTestLooper.dispatchAll();
|
||||||
|
|
@ -814,19 +790,6 @@ public final class NsdPublisherTest {
|
||||||
verify(spyNsdPublisher, times(1)).reset();
|
verify(spyNsdPublisher, times(1)).reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DnsTxtAttribute makeTxtAttribute(String name, List<Integer> value) {
|
|
||||||
DnsTxtAttribute txtAttribute = new DnsTxtAttribute();
|
|
||||||
|
|
||||||
txtAttribute.name = name;
|
|
||||||
txtAttribute.value = new byte[value.size()];
|
|
||||||
|
|
||||||
for (int i = 0; i < value.size(); ++i) {
|
|
||||||
txtAttribute.value[i] = value.get(i).byteValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
return txtAttribute;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<InetAddress> makeAddresses(String... addressStrings) {
|
private static List<InetAddress> makeAddresses(String... addressStrings) {
|
||||||
List<InetAddress> addresses = new ArrayList<>();
|
List<InetAddress> addresses = new ArrayList<>();
|
||||||
|
|
||||||
|
|
@ -836,30 +799,6 @@ public final class NsdPublisherTest {
|
||||||
return addresses;
|
return addresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TxtMatcher implements ArgumentMatcher<List<DnsTxtAttribute>> {
|
|
||||||
private final List<DnsTxtAttribute> mAttributes;
|
|
||||||
|
|
||||||
TxtMatcher(List<DnsTxtAttribute> attributes) {
|
|
||||||
mAttributes = attributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean matches(List<DnsTxtAttribute> argument) {
|
|
||||||
if (argument.size() != mAttributes.size()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < argument.size(); ++i) {
|
|
||||||
if (!Objects.equals(argument.get(i).name, mAttributes.get(i).name)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!Arrays.equals(argument.get(i).value, mAttributes.get(i).value)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Before and @Test run in different threads. NsdPublisher requires the jobs are run on the
|
// @Before and @Test run in different threads. NsdPublisher requires the jobs are run on the
|
||||||
// thread looper, so TestLooper needs to be created inside each test case to install the
|
// thread looper, so TestLooper needs to be created inside each test case to install the
|
||||||
// correct looper.
|
// correct looper.
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@ import androidx.test.filters.SmallTest;
|
||||||
import com.android.connectivity.resources.R;
|
import com.android.connectivity.resources.R;
|
||||||
import com.android.dx.mockito.inline.extended.ExtendedMockito;
|
import com.android.dx.mockito.inline.extended.ExtendedMockito;
|
||||||
import com.android.server.connectivity.ConnectivityResources;
|
import com.android.server.connectivity.ConnectivityResources;
|
||||||
|
import com.android.server.thread.openthread.DnsTxtAttribute;
|
||||||
import com.android.server.thread.openthread.MeshcopTxtAttributes;
|
import com.android.server.thread.openthread.MeshcopTxtAttributes;
|
||||||
import com.android.server.thread.openthread.testing.FakeOtDaemon;
|
import com.android.server.thread.openthread.testing.FakeOtDaemon;
|
||||||
|
|
||||||
|
|
@ -94,6 +95,7 @@ import org.mockito.Mockito;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.mockito.MockitoSession;
|
import org.mockito.MockitoSession;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.time.Clock;
|
import java.time.Clock;
|
||||||
import java.time.DateTimeException;
|
import java.time.DateTimeException;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
@ -145,6 +147,7 @@ public final class ThreadNetworkControllerServiceTest {
|
||||||
private static final byte[] TEST_VENDOR_OUI_BYTES = new byte[] {(byte) 0xAC, (byte) 0xDE, 0x48};
|
private static final byte[] TEST_VENDOR_OUI_BYTES = new byte[] {(byte) 0xAC, (byte) 0xDE, 0x48};
|
||||||
private static final String TEST_VENDOR_NAME = "test vendor";
|
private static final String TEST_VENDOR_NAME = "test vendor";
|
||||||
private static final String TEST_MODEL_NAME = "test model";
|
private static final String TEST_MODEL_NAME = "test model";
|
||||||
|
private static final boolean TEST_VGH_VALUE = false;
|
||||||
|
|
||||||
@Mock private ConnectivityManager mMockConnectivityManager;
|
@Mock private ConnectivityManager mMockConnectivityManager;
|
||||||
@Mock private NetworkAgent mMockNetworkAgent;
|
@Mock private NetworkAgent mMockNetworkAgent;
|
||||||
|
|
@ -197,6 +200,8 @@ public final class ThreadNetworkControllerServiceTest {
|
||||||
.thenReturn(TEST_VENDOR_OUI);
|
.thenReturn(TEST_VENDOR_OUI);
|
||||||
when(mResources.getString(eq(R.string.config_thread_model_name)))
|
when(mResources.getString(eq(R.string.config_thread_model_name)))
|
||||||
.thenReturn(TEST_MODEL_NAME);
|
.thenReturn(TEST_MODEL_NAME);
|
||||||
|
when(mResources.getBoolean(eq(R.bool.config_thread_managed_by_google_home)))
|
||||||
|
.thenReturn(TEST_VGH_VALUE);
|
||||||
|
|
||||||
final AtomicFile storageFile = new AtomicFile(tempFolder.newFile("thread_settings.xml"));
|
final AtomicFile storageFile = new AtomicFile(tempFolder.newFile("thread_settings.xml"));
|
||||||
mPersistentSettings = new ThreadPersistentSettings(storageFile, mConnectivityResources);
|
mPersistentSettings = new ThreadPersistentSettings(storageFile, mConnectivityResources);
|
||||||
|
|
@ -232,13 +237,15 @@ public final class ThreadNetworkControllerServiceTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void initialize_vendorAndModelNameInResourcesAreSetToOtDaemon() throws Exception {
|
public void initialize_resourceOverlayValuesAreSetToOtDaemon() throws Exception {
|
||||||
when(mResources.getString(eq(R.string.config_thread_vendor_name)))
|
when(mResources.getString(eq(R.string.config_thread_vendor_name)))
|
||||||
.thenReturn(TEST_VENDOR_NAME);
|
.thenReturn(TEST_VENDOR_NAME);
|
||||||
when(mResources.getString(eq(R.string.config_thread_vendor_oui)))
|
when(mResources.getString(eq(R.string.config_thread_vendor_oui)))
|
||||||
.thenReturn(TEST_VENDOR_OUI);
|
.thenReturn(TEST_VENDOR_OUI);
|
||||||
when(mResources.getString(eq(R.string.config_thread_model_name)))
|
when(mResources.getString(eq(R.string.config_thread_model_name)))
|
||||||
.thenReturn(TEST_MODEL_NAME);
|
.thenReturn(TEST_MODEL_NAME);
|
||||||
|
when(mResources.getBoolean(eq(R.bool.config_thread_managed_by_google_home)))
|
||||||
|
.thenReturn(true);
|
||||||
|
|
||||||
mService.initialize();
|
mService.initialize();
|
||||||
mTestLooper.dispatchAll();
|
mTestLooper.dispatchAll();
|
||||||
|
|
@ -247,6 +254,20 @@ public final class ThreadNetworkControllerServiceTest {
|
||||||
assertThat(meshcopTxts.vendorName).isEqualTo(TEST_VENDOR_NAME);
|
assertThat(meshcopTxts.vendorName).isEqualTo(TEST_VENDOR_NAME);
|
||||||
assertThat(meshcopTxts.vendorOui).isEqualTo(TEST_VENDOR_OUI_BYTES);
|
assertThat(meshcopTxts.vendorOui).isEqualTo(TEST_VENDOR_OUI_BYTES);
|
||||||
assertThat(meshcopTxts.modelName).isEqualTo(TEST_MODEL_NAME);
|
assertThat(meshcopTxts.modelName).isEqualTo(TEST_MODEL_NAME);
|
||||||
|
assertThat(meshcopTxts.nonStandardTxtEntries)
|
||||||
|
.containsExactly(new DnsTxtAttribute("vgh", "1".getBytes(StandardCharsets.UTF_8)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getMeshcopTxtAttributes_managedByGoogleIsFalse_vghIsZero() {
|
||||||
|
when(mResources.getBoolean(eq(R.bool.config_thread_managed_by_google_home)))
|
||||||
|
.thenReturn(false);
|
||||||
|
|
||||||
|
MeshcopTxtAttributes meshcopTxts =
|
||||||
|
ThreadNetworkControllerService.getMeshcopTxtAttributes(mResources);
|
||||||
|
|
||||||
|
assertThat(meshcopTxts.nonStandardTxtEntries)
|
||||||
|
.containsExactly(new DnsTxtAttribute("vgh", "0".getBytes(StandardCharsets.UTF_8)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue