Merge "Configure TREL feature from feature flag." into main

This commit is contained in:
Yang Sun 2024-11-19 06:08:23 +00:00 • committed by Gerrit Code Review
commit 41fa2d75a1
7 changed files with 122 additions and 5 deletions

View file

@ -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);
}
}

View file

@ -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()

View file

@ -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>

View file

@ -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);

View file

@ -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);
}

View file

@ -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",

View file

@ -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("");