Merge "Update longLivedTcpConnectionsExpensive value in VpnTransportInfo" am: dd52778afb am: 307dabd936 am: 36357eddcb
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2488957
Change-Id: I60de86440c90fbda4acad54064484bef366b2e3c
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 1e9352d1..21773cc 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -271,6 +271,13 @@
static final int DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT = 5 * 60;
/**
+ * Default keepalive value to consider long-lived TCP connections are expensive on the
+ * VPN network from battery usage point of view.
+ * TODO: consider reading from setting.
+ */
+ @VisibleForTesting
+ static final int DEFAULT_LONG_LIVED_TCP_CONNS_EXPENSIVE_TIMEOUT_SEC = 60;
+ /**
* Prefer using {@link IkeSessionParams.ESP_IP_VERSION_AUTO} and
* {@link IkeSessionParams.ESP_ENCAP_TYPE_AUTO} for ESP packets.
*
@@ -1670,9 +1677,12 @@
capsBuilder.setUids(createUserAndRestrictedProfilesRanges(mUserId,
mConfig.allowedApplications, mConfig.disallowedApplications));
- capsBuilder.setTransportInfo(
- new VpnTransportInfo(getActiveVpnType(), mConfig.session, mConfig.allowBypass,
- false /* longLivedTcpConnectionsExpensive */));
+ final boolean expensive = areLongLivedTcpConnectionsExpensive(mVpnRunner);
+ capsBuilder.setTransportInfo(new VpnTransportInfo(
+ getActiveVpnType(),
+ mConfig.session,
+ mConfig.allowBypass,
+ expensive));
// Only apps targeting Q and above can explicitly declare themselves as metered.
// These VPNs are assumed metered unless they state otherwise.
@@ -1704,6 +1714,17 @@
updateState(DetailedState.CONNECTED, "agentConnect");
}
+ private static boolean areLongLivedTcpConnectionsExpensive(@NonNull VpnRunner runner) {
+ if (!(runner instanceof IkeV2VpnRunner)) return false;
+
+ final int delay = ((IkeV2VpnRunner) runner).getOrGuessKeepaliveDelaySeconds();
+ return areLongLivedTcpConnectionsExpensive(delay);
+ }
+
+ private static boolean areLongLivedTcpConnectionsExpensive(int keepaliveDelaySec) {
+ return keepaliveDelaySec < DEFAULT_LONG_LIVED_TCP_CONNS_EXPENSIVE_TIMEOUT_SEC;
+ }
+
private boolean canHaveRestrictedProfile(int userId) {
final long token = Binder.clearCallingIdentity();
try {
@@ -2988,10 +3009,8 @@
// Ignore stale runner.
if (mVpnRunner != Vpn.IkeV2VpnRunner.this) return;
- maybeMigrateIkeSession(mActiveNetwork);
+ maybeMigrateIkeSessionAndUpdateVpnTransportInfo(mActiveNetwork);
}
- // TODO: update the longLivedTcpConnectionsExpensive value in the
- // networkcapabilities of the VPN network.
}
};
@@ -3442,7 +3461,7 @@
return;
}
- if (maybeMigrateIkeSession(underlyingNetwork)) return;
+ if (maybeMigrateIkeSessionAndUpdateVpnTransportInfo(underlyingNetwork)) return;
startIkeSession(underlyingNetwork);
}
@@ -3549,7 +3568,43 @@
return new CarrierConfigInfo(mccMnc, natKeepalive, encapType, ipVersion);
}
- boolean maybeMigrateIkeSession(@NonNull Network underlyingNetwork) {
+ private int getOrGuessKeepaliveDelaySeconds() {
+ if (mProfile.isAutomaticNattKeepaliveTimerEnabled()) {
+ return guessNattKeepaliveTimerForNetwork();
+ } else if (mProfile.getIkeTunnelConnectionParams() != null) {
+ return mProfile.getIkeTunnelConnectionParams()
+ .getIkeSessionParams().getNattKeepAliveDelaySeconds();
+ }
+ return DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT;
+ }
+
+ boolean maybeMigrateIkeSessionAndUpdateVpnTransportInfo(
+ @NonNull Network underlyingNetwork) {
+ final int keepaliveDelaySec = getOrGuessKeepaliveDelaySeconds();
+ final boolean migrated = maybeMigrateIkeSession(underlyingNetwork, keepaliveDelaySec);
+ if (migrated) {
+ updateVpnTransportInfoAndNetCap(keepaliveDelaySec);
+ }
+ return migrated;
+ }
+
+ public void updateVpnTransportInfoAndNetCap(int keepaliveDelaySec) {
+ final VpnTransportInfo info = new VpnTransportInfo(
+ getActiveVpnType(),
+ mConfig.session,
+ mConfig.allowBypass,
+ areLongLivedTcpConnectionsExpensive(keepaliveDelaySec));
+ final boolean ncUpdateRequired = !info.equals(mNetworkCapabilities.getTransportInfo());
+ if (ncUpdateRequired) {
+ mNetworkCapabilities = new NetworkCapabilities.Builder(mNetworkCapabilities)
+ .setTransportInfo(info)
+ .build();
+ doSendNetworkCapabilities(mNetworkAgent, mNetworkCapabilities);
+ }
+ }
+
+ private boolean maybeMigrateIkeSession(@NonNull Network underlyingNetwork,
+ int keepaliveDelaySeconds) {
if (mSession == null || !mMobikeEnabled) return false;
// IKE session can schedule a migration event only when IKE AUTH is finished
@@ -3574,15 +3629,6 @@
encapType = ESP_ENCAP_TYPE_AUTO;
}
- final int keepaliveDelaySeconds;
- if (mProfile.isAutomaticNattKeepaliveTimerEnabled()) {
- keepaliveDelaySeconds = guessNattKeepaliveTimerForNetwork();
- } else if (mProfile.getIkeTunnelConnectionParams() != null) {
- keepaliveDelaySeconds = mProfile.getIkeTunnelConnectionParams()
- .getIkeSessionParams().getNattKeepAliveDelaySeconds();
- } else {
- keepaliveDelaySeconds = DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT;
- }
mSession.setNetwork(underlyingNetwork, ipVersion, encapType, keepaliveDelaySeconds);
return true;
}
@@ -3663,7 +3709,7 @@
startOrMigrateIkeSession(mActiveNetwork);
} else if (!nc.getSubscriptionIds().equals(oldNc.getSubscriptionIds())) {
// Renew carrierConfig values.
- maybeMigrateIkeSession(mActiveNetwork);
+ maybeMigrateIkeSessionAndUpdateVpnTransportInfo(mActiveNetwork);
}
}
@@ -3691,7 +3737,7 @@
Log.d(TAG, "Data stall suspected");
// Trigger MOBIKE.
- maybeMigrateIkeSession(mActiveNetwork);
+ maybeMigrateIkeSessionAndUpdateVpnTransportInfo(mActiveNetwork);
mDataStallSuspected = true;
}
}