Configure TREL feature from feature flag.
Bug: 354868035 Bug: 359089751 Test: atest ThreadNetworkIntegrationTests:ServiceDiscoveryTest#trel_servicePublished Change-Id: Ib545df6bf5ce20f35914b4695dbd2e3c1e1232e4
This commit is contained in:
parent
9dbe69420d
commit
bb7efba754
7 changed files with 122 additions and 5 deletions
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (C) 2024 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.thread;
|
||||
|
||||
import com.android.net.module.util.DeviceConfigUtils;
|
||||
|
||||
public class FeatureFlags {
|
||||
// The namespace for Thread Network feature flags
|
||||
private static final String NAMESPACE_THREAD_NETWORK = "thread_network";
|
||||
|
||||
// The prefix for TREL feature flags
|
||||
private static final String TREL_FEATURE_PREFIX = "TrelFeature__";
|
||||
|
||||
// The feature flag for TREL enabled state
|
||||
private static final String TREL_ENABLED_FLAG = TREL_FEATURE_PREFIX + "enabled";
|
||||
|
||||
private static boolean isFeatureEnabled(String flag, boolean defaultValue) {
|
||||
return DeviceConfigUtils.getDeviceConfigPropertyBoolean(
|
||||
NAMESPACE_THREAD_NETWORK, flag, defaultValue);
|
||||
}
|
||||
|
||||
public static boolean isTrelEnabled() {
|
||||
return isFeatureEnabled(TREL_ENABLED_FLAG, false);
|
||||
}
|
||||
}
|
||||
|
|
@ -357,7 +357,8 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub
|
|||
mNsdPublisher,
|
||||
getMeshcopTxtAttributes(mResources.get()),
|
||||
mOtDaemonCallbackProxy,
|
||||
mCountryCodeSupplier.get());
|
||||
mCountryCodeSupplier.get(),
|
||||
FeatureFlags.isTrelEnabled());
|
||||
otDaemon.asBinder().linkToDeath(() -> mHandler.post(this::onOtDaemonDied), 0);
|
||||
mOtDaemon = otDaemon;
|
||||
mHandler.post(mNat64CidrController::maybeUpdateNat64Cidr);
|
||||
|
|
@ -1406,7 +1407,7 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub
|
|||
|
||||
private void setInfraLinkState(InfraLinkState newInfraLinkState) {
|
||||
if (Objects.equals(mInfraLinkState, newInfraLinkState)) {
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
LOG.i("Infra link state changed: " + mInfraLinkState + " -> " + newInfraLinkState);
|
||||
setInfraLinkInterfaceName(newInfraLinkState.interfaceName);
|
||||
|
|
@ -1417,7 +1418,7 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub
|
|||
|
||||
private void setInfraLinkInterfaceName(String newInfraLinkInterfaceName) {
|
||||
if (Objects.equals(mInfraLinkState.interfaceName, newInfraLinkInterfaceName)) {
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
ParcelFileDescriptor infraIcmp6Socket = null;
|
||||
if (newInfraLinkInterfaceName != null) {
|
||||
|
|
@ -1440,7 +1441,7 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub
|
|||
|
||||
private void setInfraLinkNat64Prefix(@Nullable String newNat64Prefix) {
|
||||
if (Objects.equals(newNat64Prefix, mInfraLinkState.nat64Prefix)) {
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
getOtDaemon()
|
||||
|
|
@ -1453,7 +1454,7 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub
|
|||
|
||||
private void setInfraLinkDnsServers(List<String> newDnsServers) {
|
||||
if (Objects.equals(newDnsServers, mInfraLinkState.dnsServers)) {
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
getOtDaemon()
|
||||
|
|
|
|||
|
|
@ -48,4 +48,10 @@
|
|||
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
|
||||
<option name="package" value="com.android.thread.tests.integration" />
|
||||
</test>
|
||||
|
||||
<!-- Enable TREL for integration tests -->
|
||||
<target_preparer class="com.android.tradefed.targetprep.FeatureFlagTargetPreparer">
|
||||
<option name="flag-value"
|
||||
value="thread_network/TrelFeature__enabled=true"/>
|
||||
</target_preparer>
|
||||
</configuration>
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@ import androidx.test.core.app.ApplicationProvider;
|
|||
import androidx.test.filters.LargeTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.net.module.util.HexDump;
|
||||
|
||||
import com.google.common.truth.Correspondence;
|
||||
|
||||
import org.junit.After;
|
||||
|
|
@ -64,6 +66,7 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
|
@ -441,6 +444,25 @@ public class ServiceDiscoveryTest {
|
|||
.containsExactly("key1", bytes(0x01, 0x02), "key2", bytes(3));
|
||||
}
|
||||
|
||||
@Test
|
||||
// TODO: move this case out to BorderRoutingTest when the service discovery utilities
|
||||
// are decoupled from this test.
|
||||
public void trelFeatureFlagEnabled_trelServicePublished() throws Exception {
|
||||
NsdServiceInfo discoveredService = discoverService(mNsdManager, "_trel._udp");
|
||||
assertThat(discoveredService).isNotNull();
|
||||
// Resolve service with the current TREL port, otherwise it may return stale service from
|
||||
// a previous infra link setup.
|
||||
NsdServiceInfo trelService =
|
||||
resolveServiceUntil(
|
||||
mNsdManager, discoveredService, s -> s.getPort() == mOtCtl.getTrelPort());
|
||||
|
||||
Map<String, byte[]> txtMap = trelService.getAttributes();
|
||||
assertThat(HexDump.toHexString(txtMap.get("xa")).toLowerCase(Locale.ROOT))
|
||||
.isEqualTo(mOtCtl.getExtendedAddr().toLowerCase(Locale.ROOT));
|
||||
assertThat(HexDump.toHexString(txtMap.get("xp")).toLowerCase(Locale.ROOT))
|
||||
.isEqualTo(mOtCtl.getExtendedPanId().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
private void registerService(NsdServiceInfo serviceInfo, RegistrationListener listener)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
mNsdManager.registerService(serviceInfo, PROTOCOL_DNS_SD, listener);
|
||||
|
|
|
|||
|
|
@ -144,6 +144,18 @@ public final class OtDaemonController {
|
|||
executeCommand("netdata register");
|
||||
}
|
||||
|
||||
public int getTrelPort() {
|
||||
return Integer.parseInt(executeCommandAndParse("trel port").get(0));
|
||||
}
|
||||
|
||||
public String getExtendedAddr() {
|
||||
return executeCommandAndParse("extaddr").get(0);
|
||||
}
|
||||
|
||||
public String getExtendedPanId() {
|
||||
return executeCommandAndParse("extpanid").get(0);
|
||||
}
|
||||
|
||||
public String executeCommand(String cmd) {
|
||||
return SystemUtil.runShellCommand(OT_CTL + " " + cmd);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ android_test {
|
|||
static_libs: [
|
||||
"androidx.test.rules",
|
||||
"frameworks-base-testutils",
|
||||
"framework-configinfrastructure.stubs.module_lib",
|
||||
"framework-connectivity-pre-jarjar",
|
||||
"framework-connectivity-t-pre-jarjar",
|
||||
"framework-location.stubs.module_lib",
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package com.android.server.thread;
|
||||
|
||||
import static android.Manifest.permission.NETWORK_SETTINGS;
|
||||
import static android.Manifest.permission.WRITE_DEVICE_CONFIG;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
|
||||
|
|
@ -34,6 +35,7 @@ import static android.net.thread.ThreadNetworkManager.PERMISSION_THREAD_NETWORK_
|
|||
|
||||
import static com.android.server.thread.ThreadNetworkCountryCode.DEFAULT_COUNTRY_CODE;
|
||||
import static com.android.server.thread.openthread.IOtDaemon.ErrorCode.OT_ERROR_INVALID_STATE;
|
||||
import static com.android.testutils.TestPermissionUtil.runAsShell;
|
||||
|
||||
import static com.google.common.io.BaseEncoding.base16;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
|
@ -85,6 +87,7 @@ import android.os.RemoteException;
|
|||
import android.os.SystemClock;
|
||||
import android.os.UserManager;
|
||||
import android.os.test.TestLooper;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.util.AtomicFile;
|
||||
|
||||
import androidx.test.annotation.UiThreadTest;
|
||||
|
|
@ -102,6 +105,7 @@ import com.android.server.thread.openthread.MeshcopTxtAttributes;
|
|||
import com.android.server.thread.openthread.OtDaemonConfiguration;
|
||||
import com.android.server.thread.openthread.testing.FakeOtDaemon;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
|
@ -258,6 +262,13 @@ public final class ThreadNetworkControllerServiceTest {
|
|||
mService.setTestNetworkAgent(mMockNetworkAgent);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
runAsShell(
|
||||
WRITE_DEVICE_CONFIG,
|
||||
() -> DeviceConfig.deleteProperty("thread_network", "TrelFeature__enabled"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_tunInterfaceAndNsdPublisherSetToOtDaemon() throws Exception {
|
||||
when(mMockTunIfController.getTunFd()).thenReturn(mMockTunFd);
|
||||
|
|
@ -323,6 +334,33 @@ public final class ThreadNetworkControllerServiceTest {
|
|||
verify(mFakeOtDaemon, times(1)).setNat64Cidr(eq(TEST_NAT64_CIDR.toString()), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_trelFeatureDisabled_trelDisabledAtOtDaemon() throws Exception {
|
||||
runAsShell(
|
||||
WRITE_DEVICE_CONFIG,
|
||||
() ->
|
||||
DeviceConfig.setProperty(
|
||||
"thread_network", "TrelFeature__enabled", "false", false));
|
||||
|
||||
mService.initialize();
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertThat(mFakeOtDaemon.isTrelEnabled()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_trelFeatureEnabled_setTrelEnabledAtOtDamon() throws Exception {
|
||||
runAsShell(
|
||||
WRITE_DEVICE_CONFIG,
|
||||
() ->
|
||||
DeviceConfig.setProperty(
|
||||
"thread_network", "TrelFeature__enabled", "true", false));
|
||||
mService.initialize();
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
assertThat(mFakeOtDaemon.isTrelEnabled()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMeshcopTxtAttributes_emptyVendorName_accepted() {
|
||||
when(mResources.getString(eq(R.string.config_thread_vendor_name))).thenReturn("");
|
||||
|
|
|
|||
Loading…
Reference in a new issue