Merge "[Cronet] Move OWNERS file to parent tests directory"
diff --git a/Tethering/apex/Android.bp b/Tethering/apex/Android.bp
index 15b3938..3f35c6b 100644
--- a/Tethering/apex/Android.bp
+++ b/Tethering/apex/Android.bp
@@ -38,6 +38,13 @@
name: "ConnectivityNextEnableDefaults",
enabled: true,
}
+java_defaults {
+ name: "NetworkStackApiShimSettingsForCurrentBranch",
+ // API shims to include in the networking modules built from the branch. Branches that disable
+ // the "next" targets must use stable shims (latest stable API level) instead of current shims
+ // (X_current API level).
+ static_libs: ["NetworkStackApiCurrentShims"],
+}
apex_defaults {
name: "ConnectivityApexDefaults",
// Tethering app to include in the AOSP apex. Branches that disable the "next" targets may use
diff --git a/service/Android.bp b/service/Android.bp
index 1523af9..e1376a1 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -138,6 +138,14 @@
name: "service-connectivity-pre-jarjar",
sdk_version: "system_server_current",
min_sdk_version: "30",
+ // NetworkStackApiShimSettingsForCurrentBranch provides the latest available shims depending on
+ // the branch to "service-connectivity".
+ // There are Tethering.apk and TetheringNext.apk variants for the tethering APEX,
+ // which use NetworkStackApiStableShims and NetworkStackApiCurrentShims respectively.
+ // Note that there can be no service-connectivity-next because it would need to be configured in
+ // default_art_config.mk which doesn't support conditionals, hence this scheme of using a
+ // variable here.
+ defaults: ["NetworkStackApiShimSettingsForCurrentBranch"],
srcs: [
"src/**/*.java",
":framework-connectivity-shared-srcs",
@@ -183,7 +191,6 @@
"PlatformProperties",
"service-connectivity-protos",
"service-connectivity-stats-protos",
- "NetworkStackApiStableShims",
],
apex_available: [
"com.android.tethering",
diff --git a/service/src/com/android/server/connectivity/AutomaticOnOffKeepaliveTracker.java b/service/src/com/android/server/connectivity/AutomaticOnOffKeepaliveTracker.java
index 6b7222a..7e288c6 100644
--- a/service/src/com/android/server/connectivity/AutomaticOnOffKeepaliveTracker.java
+++ b/service/src/com/android/server/connectivity/AutomaticOnOffKeepaliveTracker.java
@@ -18,6 +18,7 @@
import static android.net.NetworkAgent.CMD_START_SOCKET_KEEPALIVE;
import static android.net.SocketKeepalive.ERROR_INVALID_SOCKET;
+import static android.net.SocketKeepalive.MIN_INTERVAL_SEC;
import static android.net.SocketKeepalive.SUCCESS_PAUSED;
import static android.provider.DeviceConfig.NAMESPACE_TETHERING;
import static android.system.OsConstants.AF_INET;
@@ -88,8 +89,8 @@
public class AutomaticOnOffKeepaliveTracker {
private static final String TAG = "AutomaticOnOffKeepaliveTracker";
private static final int[] ADDRESS_FAMILIES = new int[] {AF_INET6, AF_INET};
- private static final long DEFAULT_TCP_POLLING_INTERVAL_MS = 120_000L;
private static final long LOW_TCP_POLLING_INTERVAL_MS = 1_000L;
+ private static final int ADJUST_TCP_POLLING_DELAY_MS = 2000;
private static final String AUTOMATIC_ON_OFF_KEEPALIVE_VERSION =
"automatic_on_off_keepalive_version";
/**
@@ -178,8 +179,7 @@
private final Network mUnderpinnedNetwork;
AutomaticOnOffKeepalive(@NonNull final KeepaliveTracker.KeepaliveInfo ki,
- final boolean autoOnOff, @NonNull Context context,
- @Nullable Network underpinnedNetwork)
+ final boolean autoOnOff, @Nullable Network underpinnedNetwork)
throws InvalidSocketException {
this.mKi = Objects.requireNonNull(ki);
mCallback = ki.mCallback;
@@ -280,12 +280,14 @@
mAlarmManager = mDependencies.getAlarmManager(context);
}
- private void startTcpPollingAlarm(@NonNull final AlarmManager.OnAlarmListener listener) {
+ private void startTcpPollingAlarm(@NonNull AutomaticOnOffKeepalive ki) {
+ if (ki.mAlarmListener == null) return;
+
final long triggerAtMillis =
- SystemClock.elapsedRealtime() + getTcpPollingInterval();
+ mDependencies.getElapsedRealtime() + getTcpPollingIntervalMs(ki);
// Setup a non-wake up alarm.
mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME, triggerAtMillis, null /* tag */,
- listener, mConnectivityServiceHandler);
+ ki.mAlarmListener, mConnectivityServiceHandler);
}
/**
@@ -322,7 +324,7 @@
handleMaybeResumeKeepalive(ki);
}
// TODO: listen to socket status instead of periodically check.
- startTcpPollingAlarm(ki.mAlarmListener);
+ startTcpPollingAlarm(ki);
}
/**
@@ -402,7 +404,7 @@
}
mAutomaticOnOffKeepalives.add(autoKi);
if (STATE_ALWAYS_ON != autoKi.mAutomaticOnOffState) {
- startTcpPollingAlarm(autoKi.mAlarmListener);
+ startTcpPollingAlarm(autoKi);
}
}
@@ -463,7 +465,7 @@
if (null == ki) return;
try {
final AutomaticOnOffKeepalive autoKi = new AutomaticOnOffKeepalive(ki,
- automaticOnOffKeepalives, mContext, underpinnedNetwork);
+ automaticOnOffKeepalives, underpinnedNetwork);
mConnectivityServiceHandler.obtainMessage(NetworkAgent.CMD_START_SOCKET_KEEPALIVE,
// TODO : move ConnectivityService#encodeBool to a static lib.
automaticOnOffKeepalives ? 1 : 0, 0, autoKi).sendToTarget();
@@ -493,7 +495,7 @@
if (null == ki) return;
try {
final AutomaticOnOffKeepalive autoKi = new AutomaticOnOffKeepalive(ki,
- automaticOnOffKeepalives, mContext, underpinnedNetwork);
+ automaticOnOffKeepalives, underpinnedNetwork);
mConnectivityServiceHandler.obtainMessage(NetworkAgent.CMD_START_SOCKET_KEEPALIVE,
// TODO : move ConnectivityService#encodeBool to a static lib.
automaticOnOffKeepalives ? 1 : 0, 0, autoKi).sendToTarget();
@@ -523,7 +525,7 @@
try {
final AutomaticOnOffKeepalive autoKi = new AutomaticOnOffKeepalive(ki,
false /* autoOnOff, tcp keepalives are never auto on/off */,
- mContext, null /* underpinnedNetwork, tcp keepalives do not refer to this */);
+ null /* underpinnedNetwork, tcp keepalives do not refer to this */);
mConnectivityServiceHandler.obtainMessage(CMD_START_SOCKET_KEEPALIVE, autoKi)
.sendToTarget();
} catch (InvalidSocketException e) {
@@ -677,9 +679,15 @@
}
}
- private long getTcpPollingInterval() {
+ private long getTcpPollingIntervalMs(@NonNull AutomaticOnOffKeepalive ki) {
final boolean useLowTimer = mTestLowTcpPollingTimerUntilMs > System.currentTimeMillis();
- return useLowTimer ? LOW_TCP_POLLING_INTERVAL_MS : DEFAULT_TCP_POLLING_INTERVAL_MS;
+ // Adjust the polling interval to be smaller than the keepalive delay to preserve
+ // some time for the system to restart the keepalive.
+ final int timer = ki.mKi.getKeepaliveIntervalSec() * 1000 - ADJUST_TCP_POLLING_DELAY_MS;
+ if (timer < MIN_INTERVAL_SEC) {
+ Log.wtf(TAG, "Unreasonably low keepalive delay: " + ki.mKi.getKeepaliveIntervalSec());
+ }
+ return useLowTimer ? LOW_TCP_POLLING_INTERVAL_MS : Math.max(timer, MIN_INTERVAL_SEC);
}
/**
@@ -786,5 +794,14 @@
return DeviceConfigUtils.isFeatureEnabled(mContext, NAMESPACE_TETHERING, name,
defaultEnabled);
}
+
+ /**
+ * Returns milliseconds since boot, including time spent in sleep.
+ *
+ * @return elapsed milliseconds since boot.
+ */
+ public long getElapsedRealtime() {
+ return SystemClock.elapsedRealtime();
+ }
}
}
diff --git a/service/src/com/android/server/connectivity/KeepaliveTracker.java b/service/src/com/android/server/connectivity/KeepaliveTracker.java
index 06294db..60485b3 100644
--- a/service/src/com/android/server/connectivity/KeepaliveTracker.java
+++ b/service/src/com/android/server/connectivity/KeepaliveTracker.java
@@ -264,6 +264,10 @@
return mSlot;
}
+ int getKeepaliveIntervalSec() {
+ return mInterval;
+ }
+
private int checkNetworkConnected() {
if (!mNai.networkInfo.isConnectedOrConnecting()) {
return ERROR_INVALID_NETWORK;
diff --git a/tests/integration/Android.bp b/tests/integration/Android.bp
index e3d80a0..12919ae 100644
--- a/tests/integration/Android.bp
+++ b/tests/integration/Android.bp
@@ -21,7 +21,10 @@
android_test {
name: "FrameworksNetIntegrationTests",
- defaults: ["framework-connectivity-internal-test-defaults"],
+ defaults: [
+ "framework-connectivity-internal-test-defaults",
+ "NetworkStackApiShimSettingsForCurrentBranch",
+ ],
platform_apis: true,
certificate: "platform",
srcs: [
@@ -33,6 +36,13 @@
"ServiceConnectivityResources",
],
static_libs: [
+ // It does not matter if NetworkStackApiStableLib or NetworkStackApiCurrentLib is used here,
+ // since the shims for the branch are already included via
+ // NetworkStackApiShimSettingsForCurrentBranch, and will be used in priority as they are
+ // first in the classpath.
+ // If the wrong shims are used for some reason, tests that use newer APIs fail.
+ // TODO: have NetworkStackApiStableLib link dynamically against the shims to remove this
+ // order-dependent setup.
"NetworkStackApiStableLib",
"androidx.test.ext.junit",
"frameworks-net-integration-testutils",
diff --git a/tests/unit/java/com/android/server/connectivity/AutomaticOnOffKeepaliveTrackerTest.java b/tests/unit/java/com/android/server/connectivity/AutomaticOnOffKeepaliveTrackerTest.java
index 4f0b9c4..696eff4 100644
--- a/tests/unit/java/com/android/server/connectivity/AutomaticOnOffKeepaliveTrackerTest.java
+++ b/tests/unit/java/com/android/server/connectivity/AutomaticOnOffKeepaliveTrackerTest.java
@@ -28,8 +28,8 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.longThat;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -57,6 +57,7 @@
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.SystemClock;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log;
@@ -94,6 +95,7 @@
private static final int NETID_MASK = 0xffff;
private static final int TIMEOUT_MS = 30_000;
private static final int MOCK_RESOURCE_ID = 5;
+ private static final int TEST_KEEPALIVE_INTERVAL_SEC = 10;
private AutomaticOnOffKeepaliveTracker mAOOKeepaliveTracker;
private HandlerThread mHandlerThread;
@@ -334,9 +336,13 @@
final KeepalivePacketData kpd = new NattKeepalivePacketData(srcAddress, srcPort,
dstAddress, dstPort, new byte[] {1});
final KeepaliveInfo ki = mKeepaliveTracker.new KeepaliveInfo(cb, nai, kpd,
- 10 /* interval */, KeepaliveInfo.TYPE_NATT, fd);
+ TEST_KEEPALIVE_INTERVAL_SEC, KeepaliveInfo.TYPE_NATT, fd);
mKeepaliveTracker.setReturnedKeepaliveInfo(ki);
+ // Mock elapsed real time to verify the alarm timer.
+ final long time = SystemClock.elapsedRealtime();
+ doReturn(time).when(mDependencies).getElapsedRealtime();
+
mAOOKeepaliveTracker.startNattKeepalive(nai, fd, 10 /* intervalSeconds */, cb,
srcAddress.toString(), srcPort, dstAddress.toString(), dstPort,
true /* automaticOnOffKeepalives */, underpinnedNetwork);
@@ -344,8 +350,11 @@
final ArgumentCaptor<AlarmManager.OnAlarmListener> listenerCaptor =
ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class);
- verify(mAlarmManager).setExact(eq(AlarmManager.ELAPSED_REALTIME), anyLong(),
- any(), listenerCaptor.capture(), eq(mTestHandler));
+ // The alarm timer should be smaller than the keepalive delay. Verify the alarm trigger time
+ // is higher than base time but smaller than the keepalive delay.
+ verify(mAlarmManager).setExact(eq(AlarmManager.ELAPSED_REALTIME),
+ longThat(t -> t > time + 1000L && t < time + TEST_KEEPALIVE_INTERVAL_SEC * 1000L),
+ any() /* tag */, listenerCaptor.capture(), eq(mTestHandler));
final AlarmManager.OnAlarmListener listener = listenerCaptor.getValue();
// For realism, the listener should be posted on the handler