Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6e8c1d6d authored by Benedict Wong's avatar Benedict Wong
Browse files

Add support for retrieval of configured VCNs by carrier privilege

This change adds support for retrieval of a list of subscription groups
that have a VCN configured.

Bug: 184612525
Test: atest FrameworksVcnTests
Change-Id: I40553a7bb45d9b1f948c7d0a791f1b22a422d55c
parent 598675ab
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -24,12 +24,15 @@ import android.net.vcn.VcnConfig;
import android.net.vcn.VcnUnderlyingNetworkPolicy;
import android.os.ParcelUuid;

import java.util.List;

/**
 * @hide
 */
interface IVcnManagementService {
    void setVcnConfig(in ParcelUuid subscriptionGroup, in VcnConfig config, in String opPkgName);
    void clearVcnConfig(in ParcelUuid subscriptionGroup, in String opPkgName);
    List<ParcelUuid> getConfiguredSubscriptionGroups(in String opPkgName);

    void addVcnUnderlyingNetworkPolicyListener(in IVcnUnderlyingNetworkPolicyListener listener);
    void removeVcnUnderlyingNetworkPolicyListener(in IVcnUnderlyingNetworkPolicyListener listener);
+19 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
@@ -162,6 +163,24 @@ public class VcnManager {
        }
    }

    /**
     * Retrieves the list of Subscription Groups for which a VCN Configuration has been set.
     *
     * <p>The returned list will include only subscription groups for which the carrier app is
     * privileged, and which have an associated {@link VcnConfig}.
     *
     * @throws SecurityException if the caller is not running as the primary user
     * @hide
     */
    @NonNull
    public List<ParcelUuid> getConfiguredSubscriptionGroups() {
        try {
            return mService.getConfiguredSubscriptionGroups(mContext.getOpPackageName());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    // TODO(b/180537630): remove all VcnUnderlyingNetworkPolicyListener refs once Telephony is using
    // the new VcnNetworkPolicyChangeListener API
    /**
+28 −0
Original line number Diff line number Diff line
@@ -614,6 +614,34 @@ public class VcnManagementService extends IVcnManagementService.Stub {
        });
    }

    /**
     * Retrieves the list of subscription groups with configured VcnConfigs
     *
     * <p>Limited to subscription groups for which the caller is carrier privileged.
     *
     * <p>Implements the IVcnManagementService Binder interface.
     */
    @Override
    @NonNull
    public List<ParcelUuid> getConfiguredSubscriptionGroups(@NonNull String opPkgName) {
        requireNonNull(opPkgName, "opPkgName was null");

        mContext.getSystemService(AppOpsManager.class)
                .checkPackage(mDeps.getBinderCallingUid(), opPkgName);
        enforcePrimaryUser();

        final List<ParcelUuid> result = new ArrayList<>();
        synchronized (mLock) {
            for (ParcelUuid subGrp : mConfigs.keySet()) {
                if (mLastSnapshot.packageHasPermissionsForSubscriptionGroup(subGrp, opPkgName)) {
                    result.add(subGrp);
                }
            }
        }

        return result;
    }

    @GuardedBy("mLock")
    private void writeConfigsToDiskLocked() {
        try {
+38 −0
Original line number Diff line number Diff line
@@ -96,6 +96,7 @@ import org.mockito.ArgumentCaptor;

import java.io.FileNotFoundException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
@@ -616,6 +617,43 @@ public class VcnManagementServiceTest {
        verify(vcnInstance).teardownAsynchronously();
    }

    @Test
    public void testGetConfiguredSubscriptionGroupsRequiresSystemUser() throws Exception {
        doReturn(UserHandle.getUid(UserHandle.MIN_SECONDARY_USER_ID, TEST_UID))
                .when(mMockDeps)
                .getBinderCallingUid();

        try {
            mVcnMgmtSvc.getConfiguredSubscriptionGroups(TEST_PACKAGE_NAME);
            fail("Expected security exception for non system user");
        } catch (SecurityException expected) {
        }
    }

    @Test
    public void testGetConfiguredSubscriptionGroupsMismatchedPackages() throws Exception {
        final String badPackage = "IncorrectPackage";
        doThrow(new SecurityException()).when(mAppOpsMgr).checkPackage(TEST_UID, badPackage);

        try {
            mVcnMgmtSvc.getConfiguredSubscriptionGroups(badPackage);
            fail("Expected security exception due to mismatched packages");
        } catch (SecurityException expected) {
        }
    }

    @Test
    public void testGetConfiguredSubscriptionGroups() throws Exception {
        mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);

        // Assert that if both UUID 1 and 2 are provisioned, the caller only gets ones that they are
        // privileged for.
        triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(TEST_UUID_1));
        final List<ParcelUuid> subGrps =
                mVcnMgmtSvc.getConfiguredSubscriptionGroups(TEST_PACKAGE_NAME);
        assertEquals(Collections.singletonList(TEST_UUID_1), subGrps);
    }

    @Test
    public void testAddVcnUnderlyingNetworkPolicyListener() throws Exception {
        mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);