Test VpnManager event for CATEGORY_EVENT_DEACTIVATED_BY_USER am: c5bf088ced

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/1955936

Change-Id: I08dfbc1cb8895bae5151c2ef1d7042d4f7c03e6b
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
lucaslin
2022-04-29 19:53:39 +00:00
committed by Automerger Merge Worker

View File

@@ -27,6 +27,7 @@ import static android.content.pm.UserInfo.FLAG_RESTRICTED;
import static android.net.ConnectivityManager.NetworkCallback;
import static android.net.INetd.IF_STATE_DOWN;
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 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.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -65,6 +67,7 @@ import android.app.AppOpsManager;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@@ -118,6 +121,7 @@ import com.android.server.IpSecService;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -271,6 +275,11 @@ public class VpnTest {
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) {
doReturn(service).when(mContext).getSystemService(name);
doReturn(name).when(mContext).getSystemServiceName(clazz);
@@ -783,6 +792,30 @@ public class VpnTest {
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
public void testStartVpnProfile() throws Exception {
final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
@@ -793,13 +826,7 @@ public class VpnTest {
vpn.startVpnProfile(TEST_VPN_PKG);
verify(mVpnProfileStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG)));
verify(mAppOps)
.noteOpNoThrow(
eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN),
eq(Process.myUid()),
eq(TEST_VPN_PKG),
eq(null) /* attributionTag */,
eq(null) /* message */);
verifyPlatformVpnIsActivated(TEST_VPN_PKG);
}
@Test
@@ -811,7 +838,7 @@ public class VpnTest {
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(),
TEST_VPN_PKG, null /* attributionTag */, null /* message */);
}
@@ -896,18 +923,7 @@ public class VpnTest {
when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG)))
.thenReturn(mVpnProfile.encode());
vpn.startVpnProfile(TEST_VPN_PKG);
verify(mAppOps).noteOpNoThrow(
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 */);
verifyPlatformVpnIsActivated(TEST_VPN_PKG);
// Add a small delay to make sure that startOp is only called once.
verify(mAppOps, after(100).times(1)).startOp(
eq(AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER),
@@ -923,12 +939,7 @@ public class VpnTest {
eq(null) /* attributionTag */,
eq(null) /* message */);
vpn.stopVpnProfile(TEST_VPN_PKG);
// Add a small delay to double confirm that startOp is only called once.
verify(mAppOps, after(100)).finishOp(
eq(AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER),
eq(Process.myUid()),
eq(TEST_VPN_PKG),
eq(null) /* attributionTag */);
verifyPlatformVpnIsDeactivated(TEST_VPN_PKG);
}
@Test
@@ -964,6 +975,60 @@ public class VpnTest {
eq(null) /* message */);
}
private void verifyVpnManagerEvent(String sessionKey, String category, int errorClass,
int errorCode) {
final Context userContext =
mContext.createContextAsUser(UserHandle.of(primaryUser.id), 0 /* flags */);
final ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(userContext, timeout(TEST_TIMEOUT_MS)).startService(
intentArgumentCaptor.capture());
final Intent intent = intentArgumentCaptor.getValue();
assertEquals(sessionKey, intent.getStringExtra(VpnManager.EXTRA_SESSION_KEY));
assertTrue(intent.getCategories().contains(category));
assertEquals(errorClass,
intent.getIntExtra(VpnManager.EXTRA_ERROR_CLASS, -1 /* defaultValue */));
assertEquals(errorCode,
intent.getIntExtra(VpnManager.EXTRA_ERROR_CODE, -1 /* defaultValue */));
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 */);
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 */);
}
@Test
public void testSetPackageAuthorizationVpnService() throws Exception {
final Vpn vpn = createVpnAndSetupUidChecks();
@@ -981,7 +1046,7 @@ public class VpnTest {
public void testSetPackageAuthorizationPlatformVpn() throws Exception {
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)
.setMode(
eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN),