Notify status callbacks when a VCN enters Safemode.

This CL updates VcnManagementService to notify VcnStatusCallbacks when
the VCN for their specified subscription group enters Safemode. In order
to be notified, the registering app must also have permissions for the
specified permission.

Bug: 163433613
Test: atest FrameworksVcnTests
Change-Id: I3242ad0ee1dc406aef56253f884c2544a994869e
This commit is contained in:
Cody Kesting
2021-02-07 12:40:53 -08:00
parent a3da6c886e
commit 59881b17b4
3 changed files with 116 additions and 6 deletions

View File

@@ -43,9 +43,11 @@ import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.annotation.NonNull;
import android.app.AppOpsManager;
import android.content.Context;
import android.net.ConnectivityManager;
@@ -72,6 +74,7 @@ import android.telephony.TelephonyManager;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.util.LocationPermissionChecker;
import com.android.server.VcnManagementService.VcnSafeModeCallback;
import com.android.server.VcnManagementService.VcnStatusCallbackInfo;
import com.android.server.vcn.TelephonySubscriptionTracker;
@@ -150,6 +153,8 @@ public class VcnManagementServiceTest {
mock(PersistableBundleUtils.LockingReadWriteHelper.class);
private final TelephonySubscriptionTracker mSubscriptionTracker =
mock(TelephonySubscriptionTracker.class);
private final LocationPermissionChecker mLocationPermissionChecker =
mock(LocationPermissionChecker.class);
private final ArgumentCaptor<VcnSafeModeCallback> mSafeModeCallbackCaptor =
ArgumentCaptor.forClass(VcnSafeModeCallback.class);
@@ -175,6 +180,7 @@ public class VcnManagementServiceTest {
doReturn(TEST_PACKAGE_NAME).when(mMockContext).getOpPackageName();
doReturn(mMockContext).when(mVcnContext).getContext();
doReturn(mTestLooper.getLooper()).when(mMockDeps).getLooper();
doReturn(TEST_UID).when(mMockDeps).getBinderCallingUid();
doReturn(mVcnContext)
@@ -192,6 +198,9 @@ public class VcnManagementServiceTest {
doReturn(mConfigReadWriteHelper)
.when(mMockDeps)
.newPersistableBundleLockingReadWriteHelper(any());
doReturn(mLocationPermissionChecker)
.when(mMockDeps)
.newLocationPermissionChecker(eq(mMockContext));
// Setup VCN instance generation
doAnswer((invocation) -> {
@@ -712,14 +721,13 @@ public class VcnManagementServiceTest {
verify(mMockPolicyListener).onPolicyChanged();
}
@Test
public void testVcnSafeModeCallbackOnEnteredSafeMode() throws Exception {
TelephonySubscriptionSnapshot snapshot =
triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(TEST_UUID_1));
private void verifyVcnSafeModeCallback(
@NonNull ParcelUuid subGroup, @NonNull TelephonySubscriptionSnapshot snapshot)
throws Exception {
verify(mMockDeps)
.newVcn(
eq(mVcnContext),
eq(TEST_UUID_1),
eq(subGroup),
eq(TEST_VCN_CONFIG),
eq(snapshot),
mSafeModeCallbackCaptor.capture());
@@ -729,10 +737,79 @@ public class VcnManagementServiceTest {
VcnSafeModeCallback safeModeCallback = mSafeModeCallbackCaptor.getValue();
safeModeCallback.onEnteredSafeMode();
assertFalse(mVcnMgmtSvc.getAllVcns().get(TEST_UUID_1).isActive());
verify(mMockPolicyListener).onPolicyChanged();
}
@Test
public void testVcnSafeModeCallbackOnEnteredSafeMode() throws Exception {
TelephonySubscriptionSnapshot snapshot =
triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(TEST_UUID_1));
verifyVcnSafeModeCallback(TEST_UUID_1, snapshot);
}
private void triggerVcnStatusCallbackOnEnteredSafeMode(
@NonNull ParcelUuid subGroup,
@NonNull String pkgName,
int uid,
boolean hasPermissionsforSubGroup,
boolean hasLocationPermission)
throws Exception {
TelephonySubscriptionSnapshot snapshot =
triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(subGroup));
doReturn(hasPermissionsforSubGroup)
.when(snapshot)
.packageHasPermissionsForSubscriptionGroup(eq(subGroup), eq(pkgName));
doReturn(hasLocationPermission)
.when(mLocationPermissionChecker)
.checkLocationPermission(eq(pkgName), any(), eq(uid), any());
mVcnMgmtSvc.registerVcnStatusCallback(subGroup, mMockStatusCallback, pkgName);
// Trigger systemReady() to set up LocationPermissionChecker
mVcnMgmtSvc.systemReady();
verifyVcnSafeModeCallback(subGroup, snapshot);
}
@Test
public void testVcnStatusCallbackOnEnteredSafeModeWithCarrierPrivileges() throws Exception {
triggerVcnStatusCallbackOnEnteredSafeMode(
TEST_UUID_1,
TEST_PACKAGE_NAME,
TEST_UID,
true /* hasPermissionsforSubGroup */,
true /* hasLocationPermission */);
verify(mMockStatusCallback, times(1)).onEnteredSafeMode();
}
@Test
public void testVcnStatusCallbackOnEnteredSafeModeWithoutCarrierPrivileges() throws Exception {
triggerVcnStatusCallbackOnEnteredSafeMode(
TEST_UUID_1,
TEST_PACKAGE_NAME,
TEST_UID,
false /* hasPermissionsforSubGroup */,
true /* hasLocationPermission */);
verify(mMockStatusCallback, never()).onEnteredSafeMode();
}
@Test
public void testVcnStatusCallbackOnEnteredSafeModeWithoutLocationPermission() throws Exception {
triggerVcnStatusCallbackOnEnteredSafeMode(
TEST_UUID_1,
TEST_PACKAGE_NAME,
TEST_UID,
true /* hasPermissionsforSubGroup */,
false /* hasLocationPermission */);
verify(mMockStatusCallback, never()).onEnteredSafeMode();
}
@Test
public void testRegisterVcnStatusCallback() throws Exception {
mVcnMgmtSvc.registerVcnStatusCallback(TEST_UUID_1, mMockStatusCallback, TEST_PACKAGE_NAME);