Disallow the legacy tether API for Wi-Fi.

AOSP code has never used this API, and metrics from production
show no usage either. Removing it will allow simplifying the
code.

This CL removes testRequestStaticIpLegacyTether because it makes
legacyTether a no-op and there is already a test for static IP
request right above it.

Bug: 408087033
Flag: EXEMPT dead code
Test: updated existing tests
Change-Id: Ib94ed0860ab57abfd9fc7bdfdc911f5ab57003ed
This commit is contained in:
Lorenzo Colitti 2025-05-13 15:37:32 +09:00
commit bec4b5b8d4
3 changed files with 29 additions and 82 deletions

View file

@ -52,6 +52,7 @@ import static android.net.TetheringManager.TETHER_ERROR_UNAVAIL_IFACE;
import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_IFACE;
import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_REQUEST;
import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_TYPE;
import static android.net.TetheringManager.TETHER_ERROR_UNSUPPORTED;
import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED;
import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED;
import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED;
@ -75,10 +76,6 @@ import static com.android.networkstack.tethering.TetheringConfiguration.TETHER_F
import static com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE;
import static com.android.networkstack.tethering.UpstreamNetworkMonitor.isCellular;
import static com.android.networkstack.tethering.metrics.TetheringStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED;
import static com.android.networkstack.tethering.metrics.TetheringStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_LEGACY_TETHER_WITH_TYPE_WIFI;
import static com.android.networkstack.tethering.metrics.TetheringStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_LEGACY_TETHER_WITH_TYPE_WIFI_P2P;
import static com.android.networkstack.tethering.metrics.TetheringStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_LEGACY_TETHER_WITH_TYPE_WIFI_P2P_SUCCESS;
import static com.android.networkstack.tethering.metrics.TetheringStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_LEGACY_TETHER_WITH_TYPE_WIFI_SUCCESS;
import static com.android.networkstack.tethering.metrics.TetheringStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_TETHER_WITH_PLACEHOLDER_REQUEST;
import static com.android.networkstack.tethering.util.TetheringMessageBase.BASE_MAIN_SM;
import static com.android.networkstack.tethering.util.TetheringUtils.createImplicitLocalOnlyTetheringRequest;
@ -1137,41 +1134,17 @@ public class Tethering {
return;
}
if (type == TETHERING_WIFI || type == TETHERING_WIFI_P2P) {
// Metrics show no usage of this legacy codepath. Stop supporing it.
sendTetherResult(listener, TETHER_ERROR_UNSUPPORTED);
return;
}
TetheringRequest request = mRequestTracker.getNextPendingRequest(type);
if (request == null) {
request = createLegacyGlobalScopeTetheringRequest(type);
}
int result = tetherInternal(request, iface);
switch (type) {
case TETHERING_WIFI:
Log.i(TAG, "Legacy tether API called on Wifi iface " + iface);
TetheringStatsLog.write(
CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED,
CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_LEGACY_TETHER_WITH_TYPE_WIFI);
if (result == TETHER_ERROR_NO_ERROR) {
Log.i(TAG, "Legacy tether API succeeded on Wifi iface " + iface);
TetheringStatsLog.write(
CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED,
CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_LEGACY_TETHER_WITH_TYPE_WIFI_SUCCESS);
}
break;
case TETHERING_WIFI_P2P:
Log.i(TAG, "Legacy tether API called on Wifi P2P iface " + iface);
TetheringStatsLog.write(
CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED,
CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_LEGACY_TETHER_WITH_TYPE_WIFI_P2P);
if (result == TETHER_ERROR_NO_ERROR) {
Log.i(TAG, "Legacy tether API succeeded on Wifi P2P iface " + iface);
TetheringStatsLog.write(
CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED,
CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_LEGACY_TETHER_WITH_TYPE_WIFI_P2P_SUCCESS);
}
break;
default:
// Do nothing
break;
}
sendTetherResult(listener, result);
sendTetherResult(listener, tetherInternal(request, iface));
}
/**
@ -1181,11 +1154,12 @@ public class Tethering {
* processInterfaceStateChanged beforehand, which is only possible for
* - WIGIG Pre-S
* - BLUETOOTH Pre-T
* It was previously supported but no longer allowed for:
* - WIFI
* - WIFI_P2P.
* Note that WIFI and WIFI_P2P already start tethering on their respective ifaces via
* WIFI_(AP/P2P_STATE_CHANGED broadcasts, which makes this API redundant for those types unless
* those broadcasts are disabled by OEM.
* because metrics show that there is no usage of this method for these types in production.
* These types start tethering on their respective ifaces via WIFI_(AP/P2P_STATE_CHANGED
* broadcasts instead.
*/
void legacyTether(String iface, final IIntResultListener listener) {
mHandler.post(() -> handleLegacyTether(iface, listener));

View file

@ -57,6 +57,7 @@ import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
import static android.net.TetheringManager.TETHER_ERROR_SERVICE_UNAVAIL;
import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_IFACE;
import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_REQUEST;
import static android.net.TetheringManager.TETHER_ERROR_UNSUPPORTED;
import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED;
import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED;
import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED;
@ -3415,39 +3416,18 @@ public class TetheringTest {
@Test
@IgnoreAfter(Build.VERSION_CODES.VANILLA_ICE_CREAM)
public void testRequestStaticIpLegacyTether() throws Exception {
public void testLegacyTetherUnsupported() throws Exception {
initTetheringOnTestThread();
// Call startTethering with static ip
final LinkAddress serverLinkAddr = new LinkAddress("192.168.0.123/24");
final LinkAddress clientLinkAddr = new LinkAddress("192.168.0.42/24");
final String serverAddr = "192.168.0.123";
final int clientAddrParceled = 0xc0a8002a;
final ArgumentCaptor<DhcpServingParamsParcel> dhcpParamsCaptor =
ArgumentCaptor.forClass(DhcpServingParamsParcel.class);
mTethering.startTethering(createTetheringRequest(TETHERING_WIFI,
serverLinkAddr, clientLinkAddr, false, CONNECTIVITY_SCOPE_GLOBAL, null),
TEST_CALLER_PKG, null);
mTethering.interfaceAdded(TEST_WIFI_IFNAME);
mLooper.dispatchAll();
verifyWifiTetheringRequested();
mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
mTethering.interfaceStatusChanged(TEST_WIFI_IFNAME, false);
mTethering.interfaceStatusChanged(TEST_WIFI_IFNAME, true);
// Call legacyTether on the interface before the link layer event comes back.
// This happens, for example, in pre-T bluetooth tethering: Settings calls startTethering,
// and then the bluetooth code calls the tether() API.
final ResultListener tetherResult = new ResultListener(TETHER_ERROR_NO_ERROR);
mTethering.legacyTether(TEST_WLAN_IFNAME, tetherResult);
final ResultListener result = new ResultListener(TETHER_ERROR_UNSUPPORTED);
mTethering.legacyTether(TEST_WIFI_IFNAME, result);
mLooper.dispatchAll();
tetherResult.assertHasResult();
// Verify that the static ip set in startTethering is used
verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr)));
verify(mIpServerDependencies, times(1)).makeDhcpServer(any(), dhcpParamsCaptor.capture(),
any());
final DhcpServingParamsParcel params = dhcpParamsCaptor.getValue();
assertEquals(serverAddr, intToInet4AddressHTH(params.serverAddr).getHostAddress());
assertEquals(24, params.serverAddrPrefixLength);
assertEquals(clientAddrParceled, params.singleClientAddr);
result.assertHasResult();
}
@Test

View file

@ -41,6 +41,7 @@ import static android.net.TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKNOWN;
import static android.net.TetheringManager.TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION;
import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_REQUEST;
import static android.net.TetheringManager.TETHER_ERROR_UNSUPPORTED;
import static android.net.cts.util.CtsTetheringUtils.isAnyIfaceMatch;
import static android.os.Process.INVALID_UID;
@ -432,28 +433,20 @@ public class TetheringManagerTest {
mCtsTetheringUtils.startWifiTethering(tetherEventCallback, softApConfig);
assertNotNull(tetheredIface);
final String wifiTetheringIface = tetheredIface.getInterface();
if (SdkLevel.isAtLeastB()) {
assertEquals(softApConfig, tetheredIface.getSoftApConfiguration());
}
mCtsTetheringUtils.stopWifiTethering(tetherEventCallback);
if (!SdkLevel.isAtLeastB()) {
final String wifiTetheringIface = tetheredIface.getInterface();
try {
final int ret = runAsShell(TETHER_PRIVILEGED,
() -> mTM.tether(wifiTetheringIface));
// There is no guarantee that the wifi interface will be available after
// disabling the hotspot, so don't fail the test if the call to tether() fails.
if (ret == TETHER_ERROR_NO_ERROR) {
// If calling #tether successful, there is a callback to tell the result of
// tethering setup.
tetherEventCallback.expectErrorOrTethered(
new TetheringInterface(TETHERING_WIFI, wifiTetheringIface));
}
} finally {
runAsShell(TETHER_PRIVILEGED, () -> mTM.untether(wifiTetheringIface));
}
if (SdkLevel.isAtLeastB()) {
assertThrows(UnsupportedOperationException.class,
() -> runAsShell(TETHER_PRIVILEGED,
() -> mTM.tether(wifiTetheringIface)));
} else {
final int ret = runAsShell(TETHER_PRIVILEGED, () -> mTM.tether(wifiTetheringIface));
assertEquals(TETHER_ERROR_UNSUPPORTED, ret);
}
} finally {
mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);