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

Commit 7381ab8e authored by Benedict Wong's avatar Benedict Wong Committed by Automerger Merge Worker
Browse files

Merge "Prevent changes to immutable capabilities for carrier wifi" am:...

Merge "Prevent changes to immutable capabilities for carrier wifi" am: 9e7e3b78 am: 12e452e7 am: b33493f9 am: 67f70151

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1661227

Change-Id: Iaca34ffe05e0ed0dca87fa0f0cc9ff5ebff0cb34
parents 11cb83b9 67f70151
Loading
Loading
Loading
Loading
+56 −1
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server;

import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_ACTIVE;
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_INACTIVE;
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_NOT_CONFIGURED;
@@ -35,7 +37,9 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.vcn.IVcnManagementService;
import android.net.vcn.IVcnStatusCallback;
import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
@@ -161,6 +165,9 @@ public class VcnManagementService extends IVcnManagementService.Stub {
    @NonNull private final VcnContext mVcnContext;
    @NonNull private final BroadcastReceiver mPkgChangeReceiver;

    @NonNull
    private final TrackingNetworkCallback mTrackingNetworkCallback = new TrackingNetworkCallback();

    /** Can only be assigned when {@link #systemReady()} is called, since it uses AppOpsManager. */
    @Nullable private LocationPermissionChecker mLocationPermissionChecker;

@@ -356,6 +363,10 @@ public class VcnManagementService extends IVcnManagementService.Stub {
    public void systemReady() {
        mContext.getSystemService(ConnectivityManager.class)
                .registerNetworkProvider(mNetworkProvider);
        mContext.getSystemService(ConnectivityManager.class)
                .registerNetworkCallback(
                        new NetworkRequest.Builder().clearCapabilities().build(),
                        mTrackingNetworkCallback);
        mTelephonySubscriptionTracker.register();
        mLocationPermissionChecker = mDeps.newLocationPermissionChecker(mVcnContext.getContext());
    }
@@ -791,8 +802,9 @@ public class VcnManagementService extends IVcnManagementService.Stub {
                        NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
            }

            final NetworkCapabilities result = ncBuilder.build();
            return new VcnUnderlyingNetworkPolicy(
                    false /* isTearDownRequested */, ncBuilder.build());
                    mTrackingNetworkCallback.requiresRestartForCarrierWifi(result), result);
        });
    }

@@ -939,6 +951,49 @@ public class VcnManagementService extends IVcnManagementService.Stub {
                @Nullable String exceptionMessage);
    }

    /**
     * TrackingNetworkCallback tracks all active networks
     *
     * <p>This is used to ensure that no underlying networks have immutable capabilities changed
     * without requiring a Network restart.
     */
    private class TrackingNetworkCallback extends ConnectivityManager.NetworkCallback {
        private final Map<Network, NetworkCapabilities> mCaps = new ArrayMap<>();

        @Override
        public void onCapabilitiesChanged(Network network, NetworkCapabilities caps) {
            synchronized (mCaps) {
                mCaps.put(network, caps);
            }
        }

        @Override
        public void onLost(Network network) {
            synchronized (mCaps) {
                mCaps.remove(network);
            }
        }

        private boolean requiresRestartForCarrierWifi(NetworkCapabilities caps) {
            if (!caps.hasTransport(TRANSPORT_WIFI) || caps.getSubIds() == null) {
                return false;
            }

            synchronized (mCaps) {
                for (NetworkCapabilities existing : mCaps.values()) {
                    if (existing.hasTransport(TRANSPORT_WIFI)
                            && caps.getSubIds().equals(existing.getSubIds())) {
                        // Restart if any immutable capabilities have changed
                        return existing.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)
                                != caps.hasCapability(NET_CAPABILITY_NOT_RESTRICTED);
                    }
                }
            }

            return false;
        }
    }

    /** VcnCallbackImpl for Vcn signals sent up to VcnManagementService. */
    private class VcnCallbackImpl implements VcnCallback {
        @NonNull private final ParcelUuid mSubGroup;
+67 −5
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server;

import static android.net.ConnectivityManager.NetworkCallback;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
@@ -55,8 +57,10 @@ import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkCapabilities.Transport;
import android.net.NetworkRequest;
import android.net.TelephonyNetworkSpecifier;
import android.net.vcn.IVcnStatusCallback;
import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
@@ -258,6 +262,10 @@ public class VcnManagementServiceTest {

        verify(mConnMgr).registerNetworkProvider(any(VcnNetworkProvider.class));
        verify(mSubscriptionTracker).register();
        verify(mConnMgr)
                .registerNetworkCallback(
                        eq(new NetworkRequest.Builder().clearCapabilities().build()),
                        any(NetworkCallback.class));
    }

    @Test
@@ -706,10 +714,8 @@ public class VcnManagementServiceTest {
                .checkLocationPermission(eq(TEST_PACKAGE_NAME), any(), eq(TEST_UID), any());
    }

    private VcnUnderlyingNetworkPolicy startVcnAndGetPolicyForTransport(
            int subId, ParcelUuid subGrp, boolean isVcnActive, int transport) {
        setupSubscriptionAndStartVcn(subId, subGrp, isVcnActive);

    private NetworkCapabilities.Builder getNetworkCapabilitiesBuilderForTransport(
            int subId, int transport) {
        final NetworkCapabilities.Builder ncBuilder =
                new NetworkCapabilities.Builder()
                        .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
@@ -718,7 +724,16 @@ public class VcnManagementServiceTest {
            ncBuilder.setSubIds(Collections.singleton(subId));
        }

        return mVcnMgmtSvc.getUnderlyingNetworkPolicy(ncBuilder.build(), new LinkProperties());
        return ncBuilder;
    }

    private VcnUnderlyingNetworkPolicy startVcnAndGetPolicyForTransport(
            int subId, ParcelUuid subGrp, boolean isVcnActive, int transport) {
        setupSubscriptionAndStartVcn(subId, subGrp, isVcnActive);

        return mVcnMgmtSvc.getUnderlyingNetworkPolicy(
                getNetworkCapabilitiesBuilderForTransport(subId, transport).build(),
                new LinkProperties());
    }

    @Test
@@ -780,6 +795,53 @@ public class VcnManagementServiceTest {
                true /* isRestricted */);
    }

    private void setupTrackedCarrierWifiNetwork(NetworkCapabilities caps) {
        mVcnMgmtSvc.systemReady();

        final ArgumentCaptor<NetworkCallback> captor =
                ArgumentCaptor.forClass(NetworkCallback.class);
        verify(mConnMgr)
                .registerNetworkCallback(
                        eq(new NetworkRequest.Builder().clearCapabilities().build()),
                        captor.capture());
        captor.getValue().onCapabilitiesChanged(new Network(0), caps);
    }

    @Test
    public void testGetUnderlyingNetworkPolicyVcnWifi_unrestrictingExistingNetworkRequiresRestart()
            throws Exception {
        final NetworkCapabilities existingNetworkCaps =
                getNetworkCapabilitiesBuilderForTransport(TEST_SUBSCRIPTION_ID, TRANSPORT_WIFI)
                        .removeCapability(NET_CAPABILITY_NOT_RESTRICTED)
                        .build();
        setupTrackedCarrierWifiNetwork(existingNetworkCaps);

        // Trigger test without VCN instance alive; expect restart due to change of NOT_RESTRICTED
        // immutable capability
        final VcnUnderlyingNetworkPolicy policy =
                mVcnMgmtSvc.getUnderlyingNetworkPolicy(
                        getNetworkCapabilitiesBuilderForTransport(
                                        TEST_SUBSCRIPTION_ID, TRANSPORT_WIFI)
                                .build(),
                        new LinkProperties());
        assertTrue(policy.isTeardownRequested());
    }

    @Test
    public void testGetUnderlyingNetworkPolicyVcnWifi_restrictingExistingNetworkRequiresRestart()
            throws Exception {
        final NetworkCapabilities existingNetworkCaps =
                getNetworkCapabilitiesBuilderForTransport(TEST_SUBSCRIPTION_ID, TRANSPORT_WIFI)
                        .build();
        setupTrackedCarrierWifiNetwork(existingNetworkCaps);

        final VcnUnderlyingNetworkPolicy policy =
                startVcnAndGetPolicyForTransport(
                        TEST_SUBSCRIPTION_ID, TEST_UUID_2, false /* isActive */, TRANSPORT_WIFI);

        assertTrue(policy.isTeardownRequested());
    }

    @Test
    public void testGetUnderlyingNetworkPolicyNonVcnNetwork() throws Exception {
        setupSubscriptionAndStartVcn(TEST_SUBSCRIPTION_ID, TEST_UUID_1, true /* isActive */);