summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Paul Hu <paulhu@google.com> 2025-03-07 09:08:42 +0000
committer Paul Hu <paulhu@google.com> 2025-03-11 06:35:30 +0000
commitcabbb7da639520633ad318655d1b5fe1c685c78e (patch)
tree358a8e055e0fa2324a43c6d99f87b55d573de2f7
parent228ccb467dd63c8caa01b90b93305049ea4410a7 (diff)
Add check to prevent resetting VPN always-on setting in safe mode
This change prevents the VPN always-on setting from being reset in safe mode, where third-party VPNs may have limited functionality in safe mode and can be deemed unsupported for always-on use. Bug: 397215751 Test: manual, VpnTest Change-Id: I03399c7c258ce5db67e81b4e51f25f2cb37700c9
-rw-r--r--services/core/java/com/android/server/connectivity/Vpn.java6
-rw-r--r--services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java26
2 files changed, 31 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index ac0892b92646..aa985907071f 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -1113,7 +1113,11 @@ public class Vpn {
}
// Remove always-on VPN if it's not supported.
if (!isAlwaysOnPackageSupported(alwaysOnPackage)) {
- setAlwaysOnPackage(null, false, null);
+ // Do not remove the always-on setting due to the restricted ability in safe mode.
+ // The always-on VPN can then start after the device reboots to normal mode.
+ if (!mContext.getPackageManager().isSafeMode()) {
+ setAlwaysOnPackage(null, false, null);
+ }
return false;
}
// Skip if the service is already established. This isn't bulletproof: it's not bound
diff --git a/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java b/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java
index 9117cc8e5ab8..a38ecc8523b1 100644
--- a/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java
+++ b/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java
@@ -3186,6 +3186,32 @@ public class VpnTest extends VpnTestBase {
assertEquals(profile, ikev2VpnProfile.toVpnProfile());
}
+ @Test
+ public void testStartAlwaysOnVpnOnSafeMode() throws Exception {
+ final Vpn vpn = createVpn(PRIMARY_USER.id);
+ setMockedUsers(PRIMARY_USER);
+
+ // UID checks must return a different UID; otherwise it'll be treated as already prepared.
+ final int uid = Process.myUid() + 1;
+ when(mPackageManager.getPackageUidAsUser(eq(TEST_VPN_PKG), anyInt()))
+ .thenReturn(uid);
+ when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG)))
+ .thenReturn(mVpnProfile.encode());
+
+ setAndVerifyAlwaysOnPackage(vpn, uid, false);
+ assertTrue(vpn.startAlwaysOnVpn());
+ assertEquals(TEST_VPN_PKG, vpn.getAlwaysOnPackage());
+
+ // Simulate safe mode and restart the always-on VPN to verify the always-on package is not
+ // reset.
+ doReturn(null).when(mVpnProfileStore).get(vpn.getProfileNameForPackage(TEST_VPN_PKG));
+ doReturn(null).when(mPackageManager).queryIntentServicesAsUser(
+ any(), any(), eq(PRIMARY_USER.id));
+ doReturn(true).when(mPackageManager).isSafeMode();
+ assertFalse(vpn.startAlwaysOnVpn());
+ assertEquals(TEST_VPN_PKG, vpn.getAlwaysOnPackage());
+ }
+
// Make it public and un-final so as to spy it
public class TestDeps extends Vpn.Dependencies {
TestDeps() {}