Merge changes from topics "CATEGORY_ERROR_IKE", "CATEGORY_ERROR_NETWORK", "CATEGORY_ERROR_USER_DEACTIVATED", "CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED"
* changes: Test VpnManager event for CATEGORY_EVENT_NETWORK_ERROR Test VpnManager event for CATEGORY_EVENT_IKE_ERROR Test VpnManager event for CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED Test VpnManager event for CATEGORY_EVENT_DEACTIVATED_BY_USER
This commit is contained in:
@@ -338,6 +338,7 @@ import com.android.net.module.util.ArrayTrackRecord;
|
|||||||
import com.android.net.module.util.CollectionUtils;
|
import com.android.net.module.util.CollectionUtils;
|
||||||
import com.android.net.module.util.LocationPermissionChecker;
|
import com.android.net.module.util.LocationPermissionChecker;
|
||||||
import com.android.networkstack.apishim.NetworkAgentConfigShimImpl;
|
import com.android.networkstack.apishim.NetworkAgentConfigShimImpl;
|
||||||
|
import com.android.networkstack.apishim.api29.ConstantsShim;
|
||||||
import com.android.server.ConnectivityService.ConnectivityDiagnosticsCallbackInfo;
|
import com.android.server.ConnectivityService.ConnectivityDiagnosticsCallbackInfo;
|
||||||
import com.android.server.ConnectivityService.NetworkRequestInfo;
|
import com.android.server.ConnectivityService.NetworkRequestInfo;
|
||||||
import com.android.server.ConnectivityServiceTest.ConnectivityServiceDependencies.ReportedInterfaces;
|
import com.android.server.ConnectivityServiceTest.ConnectivityServiceDependencies.ReportedInterfaces;
|
||||||
@@ -644,7 +645,8 @@ public class ConnectivityServiceTest {
|
|||||||
@Override
|
@Override
|
||||||
public ComponentName startService(Intent service) {
|
public ComponentName startService(Intent service) {
|
||||||
final String action = service.getAction();
|
final String action = service.getAction();
|
||||||
if (!VpnConfig.SERVICE_INTERFACE.equals(action)) {
|
if (!VpnConfig.SERVICE_INTERFACE.equals(action)
|
||||||
|
&& !ConstantsShim.ACTION_VPN_MANAGER_EVENT.equals(action)) {
|
||||||
fail("Attempt to start unknown service, action=" + action);
|
fail("Attempt to start unknown service, action=" + action);
|
||||||
}
|
}
|
||||||
return new ComponentName(service.getPackage(), "com.android.test.Service");
|
return new ComponentName(service.getPackage(), "com.android.test.Service");
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import static android.content.pm.UserInfo.FLAG_RESTRICTED;
|
|||||||
import static android.net.ConnectivityManager.NetworkCallback;
|
import static android.net.ConnectivityManager.NetworkCallback;
|
||||||
import static android.net.INetd.IF_STATE_DOWN;
|
import static android.net.INetd.IF_STATE_DOWN;
|
||||||
import static android.net.INetd.IF_STATE_UP;
|
import static android.net.INetd.IF_STATE_UP;
|
||||||
|
import static android.net.VpnManager.TYPE_VPN_PLATFORM;
|
||||||
import static android.os.UserHandle.PER_USER_RANGE;
|
import static android.os.UserHandle.PER_USER_RANGE;
|
||||||
|
|
||||||
import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
|
import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
|
||||||
@@ -54,6 +55,7 @@ import static org.mockito.Mockito.doReturn;
|
|||||||
import static org.mockito.Mockito.inOrder;
|
import static org.mockito.Mockito.inOrder;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.reset;
|
||||||
import static org.mockito.Mockito.timeout;
|
import static org.mockito.Mockito.timeout;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
@@ -65,6 +67,7 @@ import android.app.AppOpsManager;
|
|||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
@@ -88,10 +91,15 @@ import android.net.NetworkInfo.DetailedState;
|
|||||||
import android.net.RouteInfo;
|
import android.net.RouteInfo;
|
||||||
import android.net.UidRangeParcel;
|
import android.net.UidRangeParcel;
|
||||||
import android.net.VpnManager;
|
import android.net.VpnManager;
|
||||||
|
import android.net.VpnProfileState;
|
||||||
import android.net.VpnService;
|
import android.net.VpnService;
|
||||||
import android.net.VpnTransportInfo;
|
import android.net.VpnTransportInfo;
|
||||||
import android.net.ipsec.ike.IkeSessionCallback;
|
import android.net.ipsec.ike.IkeSessionCallback;
|
||||||
|
import android.net.ipsec.ike.exceptions.IkeException;
|
||||||
|
import android.net.ipsec.ike.exceptions.IkeNetworkLostException;
|
||||||
|
import android.net.ipsec.ike.exceptions.IkeNonProtocolException;
|
||||||
import android.net.ipsec.ike.exceptions.IkeProtocolException;
|
import android.net.ipsec.ike.exceptions.IkeProtocolException;
|
||||||
|
import android.net.ipsec.ike.exceptions.IkeTimeoutException;
|
||||||
import android.os.Build.VERSION_CODES;
|
import android.os.Build.VERSION_CODES;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.ConditionVariable;
|
import android.os.ConditionVariable;
|
||||||
@@ -118,6 +126,7 @@ import com.android.server.IpSecService;
|
|||||||
import com.android.testutils.DevSdkIgnoreRule;
|
import com.android.testutils.DevSdkIgnoreRule;
|
||||||
import com.android.testutils.DevSdkIgnoreRunner;
|
import com.android.testutils.DevSdkIgnoreRunner;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@@ -135,6 +144,7 @@ import java.io.FileWriter;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.Inet4Address;
|
import java.net.Inet4Address;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -271,6 +281,11 @@ public class VpnTest {
|
|||||||
doReturn(PERMISSION_DENIED).when(mContext).checkCallingOrSelfPermission(any());
|
doReturn(PERMISSION_DENIED).when(mContext).checkCallingOrSelfPermission(any());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
doReturn(PERMISSION_DENIED).when(mContext).checkCallingOrSelfPermission(CONTROL_VPN);
|
||||||
|
}
|
||||||
|
|
||||||
private <T> void mockService(Class<T> clazz, String name, T service) {
|
private <T> void mockService(Class<T> clazz, String name, T service) {
|
||||||
doReturn(service).when(mContext).getSystemService(name);
|
doReturn(service).when(mContext).getSystemService(name);
|
||||||
doReturn(name).when(mContext).getSystemServiceName(clazz);
|
doReturn(name).when(mContext).getSystemServiceName(clazz);
|
||||||
@@ -783,6 +798,30 @@ public class VpnTest {
|
|||||||
verify(mVpnProfileStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG)));
|
verify(mVpnProfileStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void verifyPlatformVpnIsActivated(String packageName) {
|
||||||
|
verify(mAppOps).noteOpNoThrow(
|
||||||
|
eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN),
|
||||||
|
eq(Process.myUid()),
|
||||||
|
eq(packageName),
|
||||||
|
eq(null) /* attributionTag */,
|
||||||
|
eq(null) /* message */);
|
||||||
|
verify(mAppOps).startOp(
|
||||||
|
eq(AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER),
|
||||||
|
eq(Process.myUid()),
|
||||||
|
eq(packageName),
|
||||||
|
eq(null) /* attributionTag */,
|
||||||
|
eq(null) /* message */);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyPlatformVpnIsDeactivated(String packageName) {
|
||||||
|
// Add a small delay to double confirm that finishOp is only called once.
|
||||||
|
verify(mAppOps, after(100)).finishOp(
|
||||||
|
eq(AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER),
|
||||||
|
eq(Process.myUid()),
|
||||||
|
eq(packageName),
|
||||||
|
eq(null) /* attributionTag */);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStartVpnProfile() throws Exception {
|
public void testStartVpnProfile() throws Exception {
|
||||||
final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
|
final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
|
||||||
@@ -793,13 +832,7 @@ public class VpnTest {
|
|||||||
vpn.startVpnProfile(TEST_VPN_PKG);
|
vpn.startVpnProfile(TEST_VPN_PKG);
|
||||||
|
|
||||||
verify(mVpnProfileStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG)));
|
verify(mVpnProfileStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG)));
|
||||||
verify(mAppOps)
|
verifyPlatformVpnIsActivated(TEST_VPN_PKG);
|
||||||
.noteOpNoThrow(
|
|
||||||
eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN),
|
|
||||||
eq(Process.myUid()),
|
|
||||||
eq(TEST_VPN_PKG),
|
|
||||||
eq(null) /* attributionTag */,
|
|
||||||
eq(null) /* message */);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -811,7 +844,7 @@ public class VpnTest {
|
|||||||
|
|
||||||
vpn.startVpnProfile(TEST_VPN_PKG);
|
vpn.startVpnProfile(TEST_VPN_PKG);
|
||||||
|
|
||||||
// Verify that the the ACTIVATE_VPN appop was checked, but no error was thrown.
|
// Verify that the ACTIVATE_VPN appop was checked, but no error was thrown.
|
||||||
verify(mAppOps).noteOpNoThrow(AppOpsManager.OPSTR_ACTIVATE_VPN, Process.myUid(),
|
verify(mAppOps).noteOpNoThrow(AppOpsManager.OPSTR_ACTIVATE_VPN, Process.myUid(),
|
||||||
TEST_VPN_PKG, null /* attributionTag */, null /* message */);
|
TEST_VPN_PKG, null /* attributionTag */, null /* message */);
|
||||||
}
|
}
|
||||||
@@ -896,18 +929,7 @@ public class VpnTest {
|
|||||||
when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG)))
|
when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG)))
|
||||||
.thenReturn(mVpnProfile.encode());
|
.thenReturn(mVpnProfile.encode());
|
||||||
vpn.startVpnProfile(TEST_VPN_PKG);
|
vpn.startVpnProfile(TEST_VPN_PKG);
|
||||||
verify(mAppOps).noteOpNoThrow(
|
verifyPlatformVpnIsActivated(TEST_VPN_PKG);
|
||||||
eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN),
|
|
||||||
eq(Process.myUid()),
|
|
||||||
eq(TEST_VPN_PKG),
|
|
||||||
eq(null) /* attributionTag */,
|
|
||||||
eq(null) /* message */);
|
|
||||||
verify(mAppOps).startOp(
|
|
||||||
eq(AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER),
|
|
||||||
eq(Process.myUid()),
|
|
||||||
eq(TEST_VPN_PKG),
|
|
||||||
eq(null) /* attributionTag */,
|
|
||||||
eq(null) /* message */);
|
|
||||||
// Add a small delay to make sure that startOp is only called once.
|
// Add a small delay to make sure that startOp is only called once.
|
||||||
verify(mAppOps, after(100).times(1)).startOp(
|
verify(mAppOps, after(100).times(1)).startOp(
|
||||||
eq(AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER),
|
eq(AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER),
|
||||||
@@ -923,12 +945,7 @@ public class VpnTest {
|
|||||||
eq(null) /* attributionTag */,
|
eq(null) /* attributionTag */,
|
||||||
eq(null) /* message */);
|
eq(null) /* message */);
|
||||||
vpn.stopVpnProfile(TEST_VPN_PKG);
|
vpn.stopVpnProfile(TEST_VPN_PKG);
|
||||||
// Add a small delay to double confirm that startOp is only called once.
|
verifyPlatformVpnIsDeactivated(TEST_VPN_PKG);
|
||||||
verify(mAppOps, after(100)).finishOp(
|
|
||||||
eq(AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER),
|
|
||||||
eq(Process.myUid()),
|
|
||||||
eq(TEST_VPN_PKG),
|
|
||||||
eq(null) /* attributionTag */);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -964,6 +981,128 @@ public class VpnTest {
|
|||||||
eq(null) /* message */);
|
eq(null) /* message */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void verifyVpnManagerEvent(String sessionKey, String category, int errorClass,
|
||||||
|
int errorCode, VpnProfileState... profileState) {
|
||||||
|
final Context userContext =
|
||||||
|
mContext.createContextAsUser(UserHandle.of(primaryUser.id), 0 /* flags */);
|
||||||
|
final ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
|
||||||
|
|
||||||
|
final int verifyTimes = (profileState == null) ? 1 : profileState.length;
|
||||||
|
verify(userContext, times(verifyTimes)).startService(intentArgumentCaptor.capture());
|
||||||
|
|
||||||
|
for (int i = 0; i < verifyTimes; i++) {
|
||||||
|
final Intent intent = intentArgumentCaptor.getAllValues().get(i);
|
||||||
|
assertEquals(sessionKey, intent.getStringExtra(VpnManager.EXTRA_SESSION_KEY));
|
||||||
|
final Set<String> categories = intent.getCategories();
|
||||||
|
assertTrue(categories.contains(category));
|
||||||
|
assertEquals(errorClass,
|
||||||
|
intent.getIntExtra(VpnManager.EXTRA_ERROR_CLASS, -1 /* defaultValue */));
|
||||||
|
assertEquals(errorCode,
|
||||||
|
intent.getIntExtra(VpnManager.EXTRA_ERROR_CODE, -1 /* defaultValue */));
|
||||||
|
if (profileState != null) {
|
||||||
|
assertEquals(profileState[i], intent.getParcelableExtra(
|
||||||
|
VpnManager.EXTRA_VPN_PROFILE_STATE, VpnProfileState.class));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reset(userContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVpnManagerEventForUserDeactivated() throws Exception {
|
||||||
|
assumeTrue(SdkLevel.isAtLeastT());
|
||||||
|
// For security reasons, Vpn#prepare() will check that oldPackage and newPackage are either
|
||||||
|
// null or the package of the caller. This test will call Vpn#prepare() to pretend the old
|
||||||
|
// VPN is replaced by a new one. But only Settings can change to some other packages, and
|
||||||
|
// this is checked with CONTROL_VPN so simulate holding CONTROL_VPN in order to pass the
|
||||||
|
// security checks.
|
||||||
|
doReturn(PERMISSION_GRANTED).when(mContext).checkCallingOrSelfPermission(CONTROL_VPN);
|
||||||
|
final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
|
||||||
|
when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG)))
|
||||||
|
.thenReturn(mVpnProfile.encode());
|
||||||
|
|
||||||
|
// Test the case that the user deactivates the vpn in vpn app.
|
||||||
|
final String sessionKey1 = vpn.startVpnProfile(TEST_VPN_PKG);
|
||||||
|
verifyPlatformVpnIsActivated(TEST_VPN_PKG);
|
||||||
|
vpn.stopVpnProfile(TEST_VPN_PKG);
|
||||||
|
verifyPlatformVpnIsDeactivated(TEST_VPN_PKG);
|
||||||
|
// CATEGORY_EVENT_DEACTIVATED_BY_USER is not an error event, so both of errorClass and
|
||||||
|
// errorCode won't be set.
|
||||||
|
verifyVpnManagerEvent(sessionKey1, VpnManager.CATEGORY_EVENT_DEACTIVATED_BY_USER,
|
||||||
|
-1 /* errorClass */, -1 /* errorCode */, null /* profileState */);
|
||||||
|
reset(mAppOps);
|
||||||
|
|
||||||
|
// Test the case that the user chooses another vpn and the original one is replaced.
|
||||||
|
final String sessionKey2 = vpn.startVpnProfile(TEST_VPN_PKG);
|
||||||
|
verifyPlatformVpnIsActivated(TEST_VPN_PKG);
|
||||||
|
vpn.prepare(TEST_VPN_PKG, "com.new.vpn" /* newPackage */, TYPE_VPN_PLATFORM);
|
||||||
|
verifyPlatformVpnIsDeactivated(TEST_VPN_PKG);
|
||||||
|
// CATEGORY_EVENT_DEACTIVATED_BY_USER is not an error event, so both of errorClass and
|
||||||
|
// errorCode won't be set.
|
||||||
|
verifyVpnManagerEvent(sessionKey2, VpnManager.CATEGORY_EVENT_DEACTIVATED_BY_USER,
|
||||||
|
-1 /* errorClass */, -1 /* errorCode */, null /* profileState */);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVpnManagerEventForAlwaysOnChanged() throws Exception {
|
||||||
|
assumeTrue(SdkLevel.isAtLeastT());
|
||||||
|
// Calling setAlwaysOnPackage() needs to hold CONTROL_VPN.
|
||||||
|
doReturn(PERMISSION_GRANTED).when(mContext).checkCallingOrSelfPermission(CONTROL_VPN);
|
||||||
|
final Vpn vpn = createVpn(primaryUser.id);
|
||||||
|
// Enable VPN always-on for PKGS[1].
|
||||||
|
assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false /* lockdown */,
|
||||||
|
null /* lockdownAllowlist */));
|
||||||
|
verifyVpnManagerEvent(null /* sessionKey */,
|
||||||
|
VpnManager.CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED, -1 /* errorClass */,
|
||||||
|
-1 /* errorCode */, new VpnProfileState(VpnProfileState.STATE_DISCONNECTED,
|
||||||
|
null /* sessionKey */, true /* alwaysOn */, false /* lockdown */));
|
||||||
|
|
||||||
|
// Enable VPN lockdown for PKGS[1].
|
||||||
|
assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true /* lockdown */,
|
||||||
|
null /* lockdownAllowlist */));
|
||||||
|
verifyVpnManagerEvent(null /* sessionKey */,
|
||||||
|
VpnManager.CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED, -1 /* errorClass */,
|
||||||
|
-1 /* errorCode */, new VpnProfileState(VpnProfileState.STATE_DISCONNECTED,
|
||||||
|
null /* sessionKey */, true /* alwaysOn */, true /* lockdown */));
|
||||||
|
|
||||||
|
// Disable VPN lockdown for PKGS[1].
|
||||||
|
assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false /* lockdown */,
|
||||||
|
null /* lockdownAllowlist */));
|
||||||
|
verifyVpnManagerEvent(null /* sessionKey */,
|
||||||
|
VpnManager.CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED, -1 /* errorClass */,
|
||||||
|
-1 /* errorCode */, new VpnProfileState(VpnProfileState.STATE_DISCONNECTED,
|
||||||
|
null /* sessionKey */, true /* alwaysOn */, false /* lockdown */));
|
||||||
|
|
||||||
|
// Disable VPN always-on.
|
||||||
|
assertTrue(vpn.setAlwaysOnPackage(null, false /* lockdown */,
|
||||||
|
null /* lockdownAllowlist */));
|
||||||
|
verifyVpnManagerEvent(null /* sessionKey */,
|
||||||
|
VpnManager.CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED, -1 /* errorClass */,
|
||||||
|
-1 /* errorCode */, new VpnProfileState(VpnProfileState.STATE_DISCONNECTED,
|
||||||
|
null /* sessionKey */, false /* alwaysOn */, false /* lockdown */));
|
||||||
|
|
||||||
|
// Enable VPN always-on for PKGS[1] again.
|
||||||
|
assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false /* lockdown */,
|
||||||
|
null /* lockdownAllowlist */));
|
||||||
|
verifyVpnManagerEvent(null /* sessionKey */,
|
||||||
|
VpnManager.CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED, -1 /* errorClass */,
|
||||||
|
-1 /* errorCode */, new VpnProfileState(VpnProfileState.STATE_DISCONNECTED,
|
||||||
|
null /* sessionKey */, true /* alwaysOn */, false /* lockdown */));
|
||||||
|
|
||||||
|
// Enable VPN always-on for PKGS[2].
|
||||||
|
assertTrue(vpn.setAlwaysOnPackage(PKGS[2], false /* lockdown */,
|
||||||
|
null /* lockdownAllowlist */));
|
||||||
|
// PKGS[1] is replaced with PKGS[2].
|
||||||
|
// Pass 2 VpnProfileState objects to verifyVpnManagerEvent(), the first one is sent to
|
||||||
|
// PKGS[1] to notify PKGS[1] that the VPN always-on is disabled, the second one is sent to
|
||||||
|
// PKGS[2] to notify PKGS[2] that the VPN always-on is enabled.
|
||||||
|
verifyVpnManagerEvent(null /* sessionKey */,
|
||||||
|
VpnManager.CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED, -1 /* errorClass */,
|
||||||
|
-1 /* errorCode */, new VpnProfileState(VpnProfileState.STATE_DISCONNECTED,
|
||||||
|
null /* sessionKey */, false /* alwaysOn */, false /* lockdown */),
|
||||||
|
new VpnProfileState(VpnProfileState.STATE_DISCONNECTED,
|
||||||
|
null /* sessionKey */, true /* alwaysOn */, false /* lockdown */));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSetPackageAuthorizationVpnService() throws Exception {
|
public void testSetPackageAuthorizationVpnService() throws Exception {
|
||||||
final Vpn vpn = createVpnAndSetupUidChecks();
|
final Vpn vpn = createVpnAndSetupUidChecks();
|
||||||
@@ -981,7 +1120,7 @@ public class VpnTest {
|
|||||||
public void testSetPackageAuthorizationPlatformVpn() throws Exception {
|
public void testSetPackageAuthorizationPlatformVpn() throws Exception {
|
||||||
final Vpn vpn = createVpnAndSetupUidChecks();
|
final Vpn vpn = createVpnAndSetupUidChecks();
|
||||||
|
|
||||||
assertTrue(vpn.setPackageAuthorization(TEST_VPN_PKG, VpnManager.TYPE_VPN_PLATFORM));
|
assertTrue(vpn.setPackageAuthorization(TEST_VPN_PKG, TYPE_VPN_PLATFORM));
|
||||||
verify(mAppOps)
|
verify(mAppOps)
|
||||||
.setMode(
|
.setMode(
|
||||||
eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN),
|
eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN),
|
||||||
@@ -1031,15 +1170,16 @@ public class VpnTest {
|
|||||||
config -> Arrays.asList(config.flags).contains(flag)));
|
config -> Arrays.asList(config.flags).contains(flag)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
private void setupPlatformVpnWithSpecificExceptionAndItsErrorCode(IkeException exception,
|
||||||
public void testStartPlatformVpnAuthenticationFailed() throws Exception {
|
String category, int errorType, int errorCode) throws Exception {
|
||||||
final ArgumentCaptor<IkeSessionCallback> captor =
|
final ArgumentCaptor<IkeSessionCallback> captor =
|
||||||
ArgumentCaptor.forClass(IkeSessionCallback.class);
|
ArgumentCaptor.forClass(IkeSessionCallback.class);
|
||||||
final IkeProtocolException exception = mock(IkeProtocolException.class);
|
|
||||||
when(exception.getErrorType())
|
|
||||||
.thenReturn(IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED);
|
|
||||||
|
|
||||||
final Vpn vpn = startLegacyVpn(createVpn(primaryUser.id), (mVpnProfile));
|
final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
|
||||||
|
when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG)))
|
||||||
|
.thenReturn(mVpnProfile.encode());
|
||||||
|
|
||||||
|
final String sessionKey = vpn.startVpnProfile(TEST_VPN_PKG);
|
||||||
final NetworkCallback cb = triggerOnAvailableAndGetCallback();
|
final NetworkCallback cb = triggerOnAvailableAndGetCallback();
|
||||||
|
|
||||||
verifyInterfaceSetCfgWithFlags(IF_STATE_UP);
|
verifyInterfaceSetCfgWithFlags(IF_STATE_UP);
|
||||||
@@ -1049,10 +1189,75 @@ public class VpnTest {
|
|||||||
verify(mIkev2SessionCreator, timeout(TEST_TIMEOUT_MS))
|
verify(mIkev2SessionCreator, timeout(TEST_TIMEOUT_MS))
|
||||||
.createIkeSession(any(), any(), any(), any(), captor.capture(), any());
|
.createIkeSession(any(), any(), any(), any(), captor.capture(), any());
|
||||||
final IkeSessionCallback ikeCb = captor.getValue();
|
final IkeSessionCallback ikeCb = captor.getValue();
|
||||||
ikeCb.onClosedExceptionally(exception);
|
ikeCb.onClosedWithException(exception);
|
||||||
|
|
||||||
verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS)).unregisterNetworkCallback(eq(cb));
|
verifyVpnManagerEvent(sessionKey, category, errorType, errorCode, null /* profileState */);
|
||||||
assertEquals(LegacyVpnInfo.STATE_FAILED, vpn.getLegacyVpnInfo().state);
|
if (errorType == VpnManager.ERROR_CLASS_NOT_RECOVERABLE) {
|
||||||
|
verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS))
|
||||||
|
.unregisterNetworkCallback(eq(cb));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStartPlatformVpnAuthenticationFailed() throws Exception {
|
||||||
|
final IkeProtocolException exception = mock(IkeProtocolException.class);
|
||||||
|
final int errorCode = IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED;
|
||||||
|
when(exception.getErrorType()).thenReturn(errorCode);
|
||||||
|
setupPlatformVpnWithSpecificExceptionAndItsErrorCode(exception,
|
||||||
|
VpnManager.CATEGORY_EVENT_IKE_ERROR, VpnManager.ERROR_CLASS_NOT_RECOVERABLE,
|
||||||
|
errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStartPlatformVpnFailedWithRecoverableError() throws Exception {
|
||||||
|
final IkeProtocolException exception = mock(IkeProtocolException.class);
|
||||||
|
final int errorCode = IkeProtocolException.ERROR_TYPE_TEMPORARY_FAILURE;
|
||||||
|
when(exception.getErrorType()).thenReturn(errorCode);
|
||||||
|
setupPlatformVpnWithSpecificExceptionAndItsErrorCode(exception,
|
||||||
|
VpnManager.CATEGORY_EVENT_IKE_ERROR, VpnManager.ERROR_CLASS_RECOVERABLE, errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStartPlatformVpnFailedWithUnknownHostException() throws Exception {
|
||||||
|
final IkeNonProtocolException exception = mock(IkeNonProtocolException.class);
|
||||||
|
final UnknownHostException unknownHostException = new UnknownHostException();
|
||||||
|
final int errorCode = VpnManager.ERROR_CODE_NETWORK_UNKNOWN_HOST;
|
||||||
|
when(exception.getCause()).thenReturn(unknownHostException);
|
||||||
|
setupPlatformVpnWithSpecificExceptionAndItsErrorCode(exception,
|
||||||
|
VpnManager.CATEGORY_EVENT_NETWORK_ERROR, VpnManager.ERROR_CLASS_RECOVERABLE,
|
||||||
|
errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStartPlatformVpnFailedWithIkeTimeoutException() throws Exception {
|
||||||
|
final IkeNonProtocolException exception = mock(IkeNonProtocolException.class);
|
||||||
|
final IkeTimeoutException ikeTimeoutException =
|
||||||
|
new IkeTimeoutException("IkeTimeoutException");
|
||||||
|
final int errorCode = VpnManager.ERROR_CODE_NETWORK_PROTOCOL_TIMEOUT;
|
||||||
|
when(exception.getCause()).thenReturn(ikeTimeoutException);
|
||||||
|
setupPlatformVpnWithSpecificExceptionAndItsErrorCode(exception,
|
||||||
|
VpnManager.CATEGORY_EVENT_NETWORK_ERROR, VpnManager.ERROR_CLASS_RECOVERABLE,
|
||||||
|
errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStartPlatformVpnFailedWithIkeNetworkLostException() throws Exception {
|
||||||
|
final IkeNetworkLostException exception = new IkeNetworkLostException(
|
||||||
|
new Network(100));
|
||||||
|
setupPlatformVpnWithSpecificExceptionAndItsErrorCode(exception,
|
||||||
|
VpnManager.CATEGORY_EVENT_NETWORK_ERROR, VpnManager.ERROR_CLASS_RECOVERABLE,
|
||||||
|
VpnManager.ERROR_CODE_NETWORK_LOST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStartPlatformVpnFailedWithIOException() throws Exception {
|
||||||
|
final IkeNonProtocolException exception = mock(IkeNonProtocolException.class);
|
||||||
|
final IOException ioException = new IOException();
|
||||||
|
final int errorCode = VpnManager.ERROR_CODE_NETWORK_IO;
|
||||||
|
when(exception.getCause()).thenReturn(ioException);
|
||||||
|
setupPlatformVpnWithSpecificExceptionAndItsErrorCode(exception,
|
||||||
|
VpnManager.CATEGORY_EVENT_NETWORK_ERROR, VpnManager.ERROR_CLASS_RECOVERABLE,
|
||||||
|
errorCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user