Merge changes I12e4d492,I4c787e9c,I52a36ebb into main
* changes: Add support for TestInterfaceMode to EthernetTracker Move call to setEthernetEnabled inside setIncludeTestInterfaces Add support for TestInterfaceMode in setIncludeTestInterfaces
This commit is contained in:
commit
23ce59740a
6 changed files with 125 additions and 32 deletions
|
|
@ -395,6 +395,45 @@ public class EthernetManager {
|
|||
removeInterfaceStateListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not include test interfaces.
|
||||
* @hide
|
||||
*/
|
||||
public static final int TEST_INTERFACE_MODE_NONE = 0;
|
||||
|
||||
/**
|
||||
* Includes test interfaces as if they were present in the regex.
|
||||
* @hide
|
||||
*/
|
||||
public static final int TEST_INTERFACE_MODE_ETHERNET = 1 << 0;
|
||||
|
||||
/**
|
||||
* Includes test interfaces as if they were NCM interfaces.
|
||||
* @hide
|
||||
*/
|
||||
public static final int TEST_INTERFACE_MODE_NCM = 1 << 1;
|
||||
|
||||
/** @hide */
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(prefix = { "TEST_INTERFACE_MODE_" }, value = {
|
||||
TEST_INTERFACE_MODE_NONE,
|
||||
TEST_INTERFACE_MODE_ETHERNET,
|
||||
TEST_INTERFACE_MODE_NCM,
|
||||
})
|
||||
public @interface TestInterfaceMode {}
|
||||
|
||||
/**
|
||||
* Version of {@code setIncludeTestInterfaces} that accepts mode flags.
|
||||
* @hide
|
||||
*/
|
||||
public void setIncludeTestInterfaces(@TestInterfaceMode int mode) {
|
||||
try {
|
||||
mService.setIncludeTestInterfaces(mode);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to treat interfaces created by {@link TestNetworkManager#createTapInterface}
|
||||
* as Ethernet interfaces. The effects of this method apply to any test interfaces that are
|
||||
|
|
@ -403,11 +442,10 @@ public class EthernetManager {
|
|||
*/
|
||||
@SystemApi(client = MODULE_LIBRARIES)
|
||||
public void setIncludeTestInterfaces(boolean include) {
|
||||
try {
|
||||
mService.setIncludeTestInterfaces(include);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
final int mode = include
|
||||
? TEST_INTERFACE_MODE_ETHERNET | TEST_INTERFACE_MODE_NCM
|
||||
: TEST_INTERFACE_MODE_NONE;
|
||||
setIncludeTestInterfaces(mode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ interface IEthernetManager
|
|||
boolean isAvailable(String iface);
|
||||
void addListener(in IEthernetServiceListener listener, int flags);
|
||||
void removeListener(in IEthernetServiceListener listener);
|
||||
void setIncludeTestInterfaces(boolean include);
|
||||
void setIncludeTestInterfaces(int mode);
|
||||
void requestTetheredInterface(in ITetheredInterfaceCallback callback);
|
||||
void releaseTetheredInterface(in ITetheredInterfaceCallback callback);
|
||||
void updateConfiguration(String iface, in EthernetNetworkUpdateRequest request,
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import android.annotation.Nullable;
|
|||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.EthernetManager;
|
||||
import android.net.EthernetManager.TestInterfaceMode;
|
||||
import android.net.EthernetNetworkSpecifier;
|
||||
import android.net.EthernetNetworkUpdateRequest;
|
||||
import android.net.IEthernetServiceListener;
|
||||
|
|
@ -208,13 +209,13 @@ public class EthernetServiceImpl extends BaseEthernetServiceImpl {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setIncludeTestInterfaces(boolean include) {
|
||||
public void setIncludeTestInterfaces(@TestInterfaceMode int mode) {
|
||||
PermissionUtils.enforceNetworkStackPermissionOr(mContext,
|
||||
android.Manifest.permission.NETWORK_SETTINGS);
|
||||
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mTracker.setIncludeTestInterfaces(include);
|
||||
mTracker.setIncludeTestInterfaces(mode);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import static android.net.NetworkCapabilities.TRANSPORT_LOWPAN;
|
|||
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
|
||||
import static android.net.TestNetworkManager.TEST_TAP_PREFIX;
|
||||
import static android.net.EthernetManager.TEST_INTERFACE_MODE_NONE;
|
||||
import static android.system.OsConstants.ENOTSUP;
|
||||
|
||||
import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
|
||||
|
|
@ -33,6 +34,7 @@ import android.annotation.NonNull;
|
|||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.net.EthernetManager;
|
||||
import android.net.EthernetManager.TestInterfaceMode;
|
||||
import android.net.INetd;
|
||||
import android.net.ITetheredInterfaceCallback;
|
||||
import android.net.InterfaceConfigurationParcel;
|
||||
|
|
@ -149,7 +151,7 @@ public class EthernetTracker {
|
|||
* Track test interfaces if true, don't track otherwise.
|
||||
* Volatile is needed as getEthernetInterfaceList() does not run on the handler thread.
|
||||
*/
|
||||
private volatile boolean mIncludeTestInterfaces = false;
|
||||
private volatile int mTestInterfaceMode = TEST_INTERFACE_MODE_NONE;
|
||||
|
||||
/** Mapping between {iface name | mac address} -> {NetworkCapabilities} */
|
||||
private final ConcurrentHashMap<String, NetworkCapabilities> mNetworkCapabilities =
|
||||
|
|
@ -561,20 +563,26 @@ public class EthernetTracker {
|
|||
mHandler.post(() -> mListeners.unregister(listener));
|
||||
}
|
||||
|
||||
public void setIncludeTestInterfaces(boolean include) {
|
||||
/** Include test interfaces as defined by the mode. */
|
||||
public void setIncludeTestInterfaces(@TestInterfaceMode int mode) {
|
||||
mHandler.post(() -> {
|
||||
mIncludeTestInterfaces = include;
|
||||
if (include) {
|
||||
mNetlinkMonitor.requestLinkDump();
|
||||
} else {
|
||||
removeTestData();
|
||||
// remove all test interfaces
|
||||
for (EthernetPort port : getAllEthernetPorts()) {
|
||||
final String iface = port.getInterfaceName();
|
||||
if (inferTrackingReason(iface).contains(TrackingReason.REGEX)) continue;
|
||||
mTestInterfaceMode = mode;
|
||||
|
||||
// A mode change requires re-evaluating all test interfaces. The simplest way is to
|
||||
// remove them all and let the netlink dump re-discover the ones that should be tracked
|
||||
// under the new mode.
|
||||
for (EthernetPort port : getAllEthernetPorts()) {
|
||||
if (isValidTestInterface(port.getInterfaceName())) {
|
||||
stopTrackingInterface(port);
|
||||
}
|
||||
}
|
||||
|
||||
if (mode != TEST_INTERFACE_MODE_NONE) {
|
||||
mNetlinkMonitor.requestLinkDump();
|
||||
} else {
|
||||
// If mode is NONE, no need for a link dump, just clean up persisted data.
|
||||
removeTestData();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -880,11 +888,13 @@ public class EthernetTracker {
|
|||
reasons.add(TrackingReason.REGEX);
|
||||
}
|
||||
|
||||
// TODO: find a way to conditionally deduce REGEX and NCM TrackingReasons for test
|
||||
// interfaces.
|
||||
if (isValidTestInterface(iface)) {
|
||||
reasons.add(TrackingReason.REGEX);
|
||||
reasons.add(TrackingReason.NCM);
|
||||
if ((mTestInterfaceMode & EthernetManager.TEST_INTERFACE_MODE_ETHERNET) != 0) {
|
||||
reasons.add(TrackingReason.REGEX);
|
||||
}
|
||||
if ((mTestInterfaceMode & EthernetManager.TEST_INTERFACE_MODE_NCM) != 0) {
|
||||
reasons.add(TrackingReason.NCM);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: remove this flag after M-2025-09 release.
|
||||
|
|
@ -920,7 +930,7 @@ public class EthernetTracker {
|
|||
* interface prefix, {@code false} otherwise.
|
||||
*/
|
||||
public boolean isValidTestInterface(@NonNull final String iface) {
|
||||
return mIncludeTestInterfaces && TEST_IFACE_REGEXP.matcher(iface).matches();
|
||||
return TEST_IFACE_REGEXP.matcher(iface).matches();
|
||||
}
|
||||
|
||||
private void postAndWaitForRunnable(Runnable r) {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package com.android.server.ethernetlegacy;
|
||||
|
||||
import static android.net.EthernetManager.TEST_INTERFACE_MODE_NONE;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_TEST;
|
||||
|
||||
|
|
@ -24,6 +25,7 @@ import android.annotation.NonNull;
|
|||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.EthernetManager.TestInterfaceMode;
|
||||
import android.net.EthernetNetworkSpecifier;
|
||||
import android.net.EthernetNetworkUpdateRequest;
|
||||
import android.net.IEthernetServiceListener;
|
||||
|
|
@ -165,7 +167,8 @@ public class EthernetServiceImpl extends BaseEthernetServiceImpl {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setIncludeTestInterfaces(boolean include) {
|
||||
public void setIncludeTestInterfaces(@TestInterfaceMode int mode) {
|
||||
final boolean include = (mode != TEST_INTERFACE_MODE_NONE);
|
||||
PermissionUtils.enforceNetworkStackPermissionOr(mContext,
|
||||
android.Manifest.permission.NETWORK_SETTINGS);
|
||||
mTracker.setIncludeTestInterfaces(include);
|
||||
|
|
|
|||
|
|
@ -24,12 +24,16 @@ import android.net.EthernetManager
|
|||
import android.net.EthernetManager.ETHERNET_STATE_DISABLED
|
||||
import android.net.EthernetManager.ETHERNET_STATE_ENABLED
|
||||
import android.net.EthernetManager.InterfaceStateListener
|
||||
import android.net.EthernetManager.LISTENER_FLAG_DEFAULT
|
||||
import android.net.EthernetManager.LISTENER_FLAG_INCLUDE_NCM
|
||||
import android.net.EthernetManager.ROLE_CLIENT
|
||||
import android.net.EthernetManager.ROLE_NONE
|
||||
import android.net.EthernetManager.ROLE_SERVER
|
||||
import android.net.EthernetManager.STATE_ABSENT
|
||||
import android.net.EthernetManager.STATE_LINK_DOWN
|
||||
import android.net.EthernetManager.STATE_LINK_UP
|
||||
import android.net.EthernetManager.TEST_INTERFACE_MODE_ETHERNET
|
||||
import android.net.EthernetManager.TEST_INTERFACE_MODE_NCM
|
||||
import android.net.EthernetManager.TetheredInterfaceCallback
|
||||
import android.net.EthernetManager.TetheredInterfaceRequest
|
||||
import android.net.EthernetNetworkManagementException
|
||||
|
|
@ -377,7 +381,7 @@ class EthernetManagerTest {
|
|||
fun setUp() {
|
||||
assumeTrue(isEthernetSupported())
|
||||
setIncludeTestInterfaces(true)
|
||||
addInterfaceStateListener(ifaceListener)
|
||||
addInterfaceStateListener(ifaceListener, LISTENER_FLAG_INCLUDE_NCM)
|
||||
// Handler.post() events may get processed after native fd events, so it is possible that
|
||||
// RTM_NEWLINK (from a subsequent createInterface() call) arrives before the interface state
|
||||
// listener is registered. This affects the callbacks and breaks the tests.
|
||||
|
|
@ -436,8 +440,11 @@ class EthernetManagerTest {
|
|||
SystemProperties.getInt("service.adb.tcp.port", -1) > -1)
|
||||
}
|
||||
|
||||
private fun addInterfaceStateListener(listener: EthernetStateListener) {
|
||||
em.addInterfaceStateListener(handler::post, listener)
|
||||
private fun addInterfaceStateListener(
|
||||
listener: EthernetStateListener,
|
||||
flags: Int = LISTENER_FLAG_DEFAULT,
|
||||
) {
|
||||
em.addInterfaceStateListener(handler::post, listener, flags)
|
||||
addedListeners.add(listener)
|
||||
}
|
||||
|
||||
|
|
@ -467,6 +474,18 @@ class EthernetManagerTest {
|
|||
runAsShell(NETWORK_SETTINGS) {
|
||||
em.setIncludeTestInterfaces(value)
|
||||
}
|
||||
// Wait for the call to be processed by calling setEthernetEnabled() which waits on a
|
||||
// completion callback.
|
||||
setEthernetEnabled(ethernetEnabled)
|
||||
}
|
||||
|
||||
private fun setIncludeTestInterfaces(mode: Int) {
|
||||
runAsShell(NETWORK_SETTINGS) {
|
||||
em.setIncludeTestInterfaces(mode)
|
||||
}
|
||||
// Wait for the call to be processed by calling setEthernetEnabled() which waits on a
|
||||
// completion callback.
|
||||
setEthernetEnabled(ethernetEnabled)
|
||||
}
|
||||
|
||||
private fun removeInterface(iface: EthernetTestInterface) {
|
||||
|
|
@ -710,18 +729,15 @@ class EthernetManagerTest {
|
|||
val iface2 = createInterface()
|
||||
val iface3 = createInterface()
|
||||
|
||||
// Prevent test interfaces from being tracked and wait for the call to be processed by
|
||||
// calling setEthernetEnabled() which waits on a completion callback.
|
||||
// Prevent test interfaces from being tracked.
|
||||
setIncludeTestInterfaces(false)
|
||||
setEthernetEnabled(true)
|
||||
|
||||
val listener = EthernetStateListener()
|
||||
addInterfaceStateListener(listener)
|
||||
listener.assertNoCallback()
|
||||
|
||||
// Include test interfaces again, and ensure that they are tracked properly.
|
||||
// Include test interfaces again.
|
||||
setIncludeTestInterfaces(true)
|
||||
setEthernetEnabled(true)
|
||||
|
||||
listener.expectCallback(iface1, STATE_LINK_UP, ROLE_CLIENT)
|
||||
listener.expectCallback(iface2, STATE_LINK_UP, ROLE_CLIENT)
|
||||
|
|
@ -1217,4 +1233,29 @@ class EthernetManagerTest {
|
|||
releaseRequest(cb2)
|
||||
cb.expect<Available>()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNcmOnlyNetwork() {
|
||||
setIncludeTestInterfaces(TEST_INTERFACE_MODE_NCM)
|
||||
val iface = createInterface()
|
||||
|
||||
val eth = requestNetwork(ETH_REQUEST)
|
||||
eth.assertNoCallback()
|
||||
|
||||
val ncm = runAsShell(CONNECTIVITY_USE_RESTRICTED_NETWORKS) { requestNetwork(LOCAL_REQUEST) }
|
||||
ncm.expect<Available>()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNonNcmNetwork() {
|
||||
setIncludeTestInterfaces(TEST_INTERFACE_MODE_ETHERNET)
|
||||
val iface = createInterface()
|
||||
|
||||
val eth = requestNetwork(ETH_REQUEST)
|
||||
eth.expect<Available>()
|
||||
|
||||
val ncm = runAsShell(CONNECTIVITY_USE_RESTRICTED_NETWORKS) { requestNetwork(LOCAL_REQUEST) }
|
||||
ncm.assertNoCallback()
|
||||
eth.assertNeverLost()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue