Merge "Fix an infinite loop with network offers"
diff --git a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
index 5b39a23..de76e89 100644
--- a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
+++ b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
@@ -131,6 +131,11 @@
@VisibleForTesting
static final int NF_CONNTRACK_UDP_TIMEOUT_STREAM = 180;
+ // List of TCP port numbers which aren't offloaded because the packets require the netfilter
+ // conntrack helper. See also TetherController::setForwardRules in netd.
+ static final short [] NON_OFFLOADED_UPSTREAM_IPV4_TCP_PORTS = new short [] {
+ 21 /* ftp */, 1723 /* pptp */};
+
@VisibleForTesting
enum StatsType {
STATS_PER_IFACE,
@@ -1556,7 +1561,18 @@
0 /* lastUsed, filled by bpf prog only */);
}
+ private boolean requireOffload(ConntrackEvent e) {
+ if (e.tupleOrig.protoNum != OsConstants.IPPROTO_TCP) return true;
+
+ for (final short port : NON_OFFLOADED_UPSTREAM_IPV4_TCP_PORTS) {
+ if (port == e.tupleOrig.dstPort) return false;
+ }
+ return true;
+ }
+
public void accept(ConntrackEvent e) {
+ if (!requireOffload(e)) return;
+
final ClientInfo tetherClient = getClientInfo(e.tupleOrig.srcIp);
if (tetherClient == null) return;
diff --git a/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java b/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java
index 4d60279..80951ca 100644
--- a/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java
@@ -17,6 +17,7 @@
package android.net.cts;
import static android.Manifest.permission.UPDATE_DEVICE_STATS;
+import static android.content.pm.PackageManager.FEATURE_TELEPHONY;
import static androidx.test.InstrumentationRegistry.getContext;
@@ -28,9 +29,11 @@
import static org.junit.Assert.fail;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.cts.util.CtsNetUtils;
+import android.net.wifi.WifiManager;
import android.os.BatteryStatsManager;
import android.os.Build;
import android.os.connectivity.CellularBatteryStats;
@@ -72,6 +75,8 @@
private Context mContext;
private BatteryStatsManager mBsm;
private ConnectivityManager mCm;
+ private WifiManager mWm;
+ private PackageManager mPm;
private CtsNetUtils mCtsNetUtils;
@Before
@@ -79,9 +84,14 @@
mContext = getContext();
mBsm = mContext.getSystemService(BatteryStatsManager.class);
mCm = mContext.getSystemService(ConnectivityManager.class);
+ mWm = mContext.getSystemService(WifiManager.class);
+ mPm = mContext.getPackageManager();
mCtsNetUtils = new CtsNetUtils(mContext);
}
+ // reportNetworkInterfaceForTransports classifies one network interface as wifi or mobile, so
+ // check that the interface is classified properly by checking the data usage is reported
+ // properly.
@Test
@AppModeFull(reason = "Cannot get CHANGE_NETWORK_STATE to request wifi/cell in instant mode")
@SkipPresubmit(reason = "Virtual hardware does not support wifi battery stats")
@@ -108,42 +118,9 @@
// Make sure wifi is disabled.
mCtsNetUtils.ensureWifiDisconnected(null /* wifiNetworkToCheck */);
- final Network cellNetwork = mCtsNetUtils.connectToCell();
- final URL url = new URL(TEST_URL);
+ verifyGetCellBatteryStats();
+ verifyGetWifiBatteryStats();
- // Get cellular battery stats
- CellularBatteryStats cellularStatsBefore = runAsShell(UPDATE_DEVICE_STATS,
- mBsm::getCellularBatteryStats);
-
- // Generate traffic on cellular network.
- Log.d(TAG, "Generate traffic on cellular network.");
- generateNetworkTraffic(cellNetwork, url);
-
- // The mobile battery stats are updated when a network stops being the default network.
- // ConnectivityService will call BatteryStatsManager.reportMobileRadioPowerState when
- // removing data activity tracking.
- final Network wifiNetwork = mCtsNetUtils.ensureWifiConnected();
-
- // Check cellular battery stats are updated.
- runAsShell(UPDATE_DEVICE_STATS,
- () -> assertStatsEventually(mBsm::getCellularBatteryStats,
- cellularStatsAfter -> cellularBatteryStatsIncreased(
- cellularStatsBefore, cellularStatsAfter)));
-
- WifiBatteryStats wifiStatsBefore = runAsShell(UPDATE_DEVICE_STATS,
- mBsm::getWifiBatteryStats);
-
- // Generate traffic on wifi network.
- Log.d(TAG, "Generate traffic on wifi network.");
- generateNetworkTraffic(wifiNetwork, url);
- // Wifi battery stats are updated when wifi on.
- mCtsNetUtils.toggleWifi();
-
- // Check wifi battery stats are updated.
- runAsShell(UPDATE_DEVICE_STATS,
- () -> assertStatsEventually(mBsm::getWifiBatteryStats,
- wifiStatsAfter -> wifiBatteryStatsIncreased(wifiStatsBefore,
- wifiStatsAfter)));
} finally {
// Reset battery settings.
executeShellCommand("dumpsys batterystats disable no-auto-reset");
@@ -151,6 +128,62 @@
}
}
+ private void verifyGetCellBatteryStats() throws Exception {
+ final boolean isTelephonySupported = mPm.hasSystemFeature(FEATURE_TELEPHONY);
+
+ if (!isTelephonySupported) {
+ Log.d(TAG, "Skip cell battery stats test because device does not support telephony.");
+ return;
+ }
+
+ final Network cellNetwork = mCtsNetUtils.connectToCell();
+ final URL url = new URL(TEST_URL);
+
+ // Get cellular battery stats
+ CellularBatteryStats cellularStatsBefore = runAsShell(UPDATE_DEVICE_STATS,
+ mBsm::getCellularBatteryStats);
+
+ // Generate traffic on cellular network.
+ Log.d(TAG, "Generate traffic on cellular network.");
+ generateNetworkTraffic(cellNetwork, url);
+
+ // The mobile battery stats are updated when a network stops being the default network.
+ // ConnectivityService will call BatteryStatsManager.reportMobileRadioPowerState when
+ // removing data activity tracking.
+ mCtsNetUtils.ensureWifiConnected();
+
+ // Check cellular battery stats are updated.
+ runAsShell(UPDATE_DEVICE_STATS,
+ () -> assertStatsEventually(mBsm::getCellularBatteryStats,
+ cellularStatsAfter -> cellularBatteryStatsIncreased(
+ cellularStatsBefore, cellularStatsAfter)));
+ }
+
+ private void verifyGetWifiBatteryStats() throws Exception {
+ final Network wifiNetwork = mCtsNetUtils.ensureWifiConnected();
+ final URL url = new URL(TEST_URL);
+
+ if (!mWm.isEnhancedPowerReportingSupported()) {
+ Log.d(TAG, "Skip wifi stats test because wifi does not support link layer stats.");
+ return;
+ }
+
+ WifiBatteryStats wifiStatsBefore = runAsShell(UPDATE_DEVICE_STATS,
+ mBsm::getWifiBatteryStats);
+
+ // Generate traffic on wifi network.
+ Log.d(TAG, "Generate traffic on wifi network.");
+ generateNetworkTraffic(wifiNetwork, url);
+ // Wifi battery stats are updated when wifi on.
+ mCtsNetUtils.toggleWifi();
+
+ // Check wifi battery stats are updated.
+ runAsShell(UPDATE_DEVICE_STATS,
+ () -> assertStatsEventually(mBsm::getWifiBatteryStats,
+ wifiStatsAfter -> wifiBatteryStatsIncreased(wifiStatsBefore,
+ wifiStatsAfter)));
+ }
+
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
@Test