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

Commit 6d02108d authored by Cody Kesting's avatar Cody Kesting Committed by Gerrit Code Review
Browse files

Merge changes I03be15d6,Ie1671925,Ie87f4aa3,I24474419,I15bc9aaf

* changes:
  Fix test method naming in VcnManagementServiceTest.
  Fix field order for UnderlyingNetworkTracker.
  Notify PolicyListeners to refresh their policy on VCN changes.
  Unit test TelephonySubscriptionSnapshot changes for VCNs.
  Notify UnderlyingNetworkTracker for Subscription changes.
parents e412ab4e f5915a7f
Loading
Loading
Loading
Loading
+35 −7
Original line number Original line Diff line number Diff line
@@ -290,8 +290,9 @@ public class VcnManagementService extends IVcnManagementService.Stub {
        public Vcn newVcn(
        public Vcn newVcn(
                @NonNull VcnContext vcnContext,
                @NonNull VcnContext vcnContext,
                @NonNull ParcelUuid subscriptionGroup,
                @NonNull ParcelUuid subscriptionGroup,
                @NonNull VcnConfig config) {
                @NonNull VcnConfig config,
            return new Vcn(vcnContext, subscriptionGroup, config);
                @NonNull TelephonySubscriptionSnapshot snapshot) {
            return new Vcn(vcnContext, subscriptionGroup, config, snapshot);
        }
        }


        /** Gets the subId indicated by the given {@link WifiInfo}. */
        /** Gets the subId indicated by the given {@link WifiInfo}. */
@@ -382,6 +383,7 @@ public class VcnManagementService extends IVcnManagementService.Stub {
                // delay)
                // delay)
                for (Entry<ParcelUuid, Vcn> entry : mVcns.entrySet()) {
                for (Entry<ParcelUuid, Vcn> entry : mVcns.entrySet()) {
                    final VcnConfig config = mConfigs.get(entry.getKey());
                    final VcnConfig config = mConfigs.get(entry.getKey());

                    if (config == null
                    if (config == null
                            || !snapshot.packageHasPermissionsForSubscriptionGroup(
                            || !snapshot.packageHasPermissionsForSubscriptionGroup(
                                    entry.getKey(), config.getProvisioningPackageName())) {
                                    entry.getKey(), config.getProvisioningPackageName())) {
@@ -395,16 +397,40 @@ public class VcnManagementService extends IVcnManagementService.Stub {
                                // correct instance is torn down. This could happen as a result of a
                                // correct instance is torn down. This could happen as a result of a
                                // Carrier App manually removing/adding a VcnConfig.
                                // Carrier App manually removing/adding a VcnConfig.
                                if (mVcns.get(uuidToTeardown) == instanceToTeardown) {
                                if (mVcns.get(uuidToTeardown) == instanceToTeardown) {
                                    mVcns.remove(uuidToTeardown).teardownAsynchronously();
                                    stopVcnLocked(uuidToTeardown);
                                }
                                }
                            }
                            }
                        }, instanceToTeardown, CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS);
                        }, instanceToTeardown, CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS);
                    } else {
                        // If this VCN's status has not changed, update it with the new snapshot
                        entry.getValue().updateSubscriptionSnapshot(mLastSnapshot);
                    }
                    }
                }
                }
            }
            }
        }
        }
    }
    }


    @GuardedBy("mLock")
    private void stopVcnLocked(@NonNull ParcelUuid uuidToTeardown) {
        final Vcn vcnToTeardown = mVcns.remove(uuidToTeardown);
        if (vcnToTeardown == null) {
            return;
        }

        vcnToTeardown.teardownAsynchronously();

        // Now that the VCN is removed, notify all registered listeners to refresh their
        // UnderlyingNetworkPolicy.
        notifyAllPolicyListenersLocked();
    }

    @GuardedBy("mLock")
    private void notifyAllPolicyListenersLocked() {
        for (final PolicyListenerBinderDeath policyListener : mRegisteredPolicyListeners.values()) {
            Binder.withCleanCallingIdentity(() -> policyListener.mListener.onPolicyChanged());
        }
    }

    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private void startVcnLocked(@NonNull ParcelUuid subscriptionGroup, @NonNull VcnConfig config) {
    private void startVcnLocked(@NonNull ParcelUuid subscriptionGroup, @NonNull VcnConfig config) {
        Slog.v(TAG, "Starting VCN config for subGrp: " + subscriptionGroup);
        Slog.v(TAG, "Starting VCN config for subGrp: " + subscriptionGroup);
@@ -412,8 +438,12 @@ public class VcnManagementService extends IVcnManagementService.Stub {
        // TODO(b/176939047): Support multiple VCNs active at the same time, or limit to one active
        // TODO(b/176939047): Support multiple VCNs active at the same time, or limit to one active
        //                    VCN.
        //                    VCN.


        final Vcn newInstance = mDeps.newVcn(mVcnContext, subscriptionGroup, config);
        final Vcn newInstance = mDeps.newVcn(mVcnContext, subscriptionGroup, config, mLastSnapshot);
        mVcns.put(subscriptionGroup, newInstance);
        mVcns.put(subscriptionGroup, newInstance);

        // Now that a new VCN has started, notify all registered listeners to refresh their
        // UnderlyingNetworkPolicy.
        notifyAllPolicyListenersLocked();
    }
    }


    @GuardedBy("mLock")
    @GuardedBy("mLock")
@@ -476,9 +506,7 @@ public class VcnManagementService extends IVcnManagementService.Stub {
            synchronized (mLock) {
            synchronized (mLock) {
                mConfigs.remove(subscriptionGroup);
                mConfigs.remove(subscriptionGroup);


                if (mVcns.containsKey(subscriptionGroup)) {
                stopVcnLocked(subscriptionGroup);
                    mVcns.remove(subscriptionGroup).teardownAsynchronously();
                }


                writeConfigsToDiskLocked();
                writeConfigsToDiskLocked();
            }
            }
+49 −34
Original line number Original line Diff line number Diff line
@@ -28,16 +28,15 @@ import android.net.NetworkRequest;
import android.net.TelephonyNetworkSpecifier;
import android.net.TelephonyNetworkSpecifier;
import android.os.Handler;
import android.os.Handler;
import android.os.ParcelUuid;
import android.os.ParcelUuid;
import android.telephony.SubscriptionInfo;
import android.util.ArrayMap;
import android.telephony.SubscriptionManager;
import android.util.ArraySet;
import android.util.ArraySet;
import android.util.Slog;
import android.util.Slog;
import android.util.SparseArray;


import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting.Visibility;
import com.android.internal.annotations.VisibleForTesting.Visibility;
import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;


import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Objects;
import java.util.Set;
import java.util.Set;


@@ -55,19 +54,18 @@ public class UnderlyingNetworkTracker {


    @NonNull private final VcnContext mVcnContext;
    @NonNull private final VcnContext mVcnContext;
    @NonNull private final ParcelUuid mSubscriptionGroup;
    @NonNull private final ParcelUuid mSubscriptionGroup;
    @NonNull private final Set<Integer> mRequiredUnderlyingNetworkCapabilities;
    @NonNull private final UnderlyingNetworkTrackerCallback mCb;
    @NonNull private final UnderlyingNetworkTrackerCallback mCb;
    @NonNull private final Dependencies mDeps;
    @NonNull private final Dependencies mDeps;
    @NonNull private final Handler mHandler;
    @NonNull private final Handler mHandler;
    @NonNull private final ConnectivityManager mConnectivityManager;
    @NonNull private final ConnectivityManager mConnectivityManager;
    @NonNull private final SubscriptionManager mSubscriptionManager;


    @NonNull private final SparseArray<NetworkCallback> mCellBringupCallbacks = new SparseArray<>();
    @NonNull private final Map<Integer, NetworkCallback> mCellBringupCallbacks = new ArrayMap<>();
    @NonNull private final NetworkCallback mWifiBringupCallback = new NetworkBringupCallback();
    @NonNull private final NetworkCallback mWifiBringupCallback = new NetworkBringupCallback();
    @NonNull private final NetworkCallback mRouteSelectionCallback = new RouteSelectionCallback();
    @NonNull private final NetworkCallback mRouteSelectionCallback = new RouteSelectionCallback();


    @NonNull private final Set<Integer> mSubIds = new ArraySet<>();
    @NonNull private TelephonySubscriptionSnapshot mLastSnapshot;

    private boolean mIsRunning = true;
    @NonNull private final Set<Integer> mRequiredUnderlyingNetworkCapabilities;


    @Nullable private UnderlyingNetworkRecord mCurrentRecord;
    @Nullable private UnderlyingNetworkRecord mCurrentRecord;
    @Nullable private UnderlyingNetworkRecord.Builder mRecordInProgress;
    @Nullable private UnderlyingNetworkRecord.Builder mRecordInProgress;
@@ -75,11 +73,13 @@ public class UnderlyingNetworkTracker {
    public UnderlyingNetworkTracker(
    public UnderlyingNetworkTracker(
            @NonNull VcnContext vcnContext,
            @NonNull VcnContext vcnContext,
            @NonNull ParcelUuid subscriptionGroup,
            @NonNull ParcelUuid subscriptionGroup,
            @NonNull TelephonySubscriptionSnapshot snapshot,
            @NonNull Set<Integer> requiredUnderlyingNetworkCapabilities,
            @NonNull Set<Integer> requiredUnderlyingNetworkCapabilities,
            @NonNull UnderlyingNetworkTrackerCallback cb) {
            @NonNull UnderlyingNetworkTrackerCallback cb) {
        this(
        this(
                vcnContext,
                vcnContext,
                subscriptionGroup,
                subscriptionGroup,
                snapshot,
                requiredUnderlyingNetworkCapabilities,
                requiredUnderlyingNetworkCapabilities,
                cb,
                cb,
                new Dependencies());
                new Dependencies());
@@ -88,11 +88,13 @@ public class UnderlyingNetworkTracker {
    private UnderlyingNetworkTracker(
    private UnderlyingNetworkTracker(
            @NonNull VcnContext vcnContext,
            @NonNull VcnContext vcnContext,
            @NonNull ParcelUuid subscriptionGroup,
            @NonNull ParcelUuid subscriptionGroup,
            @NonNull TelephonySubscriptionSnapshot snapshot,
            @NonNull Set<Integer> requiredUnderlyingNetworkCapabilities,
            @NonNull Set<Integer> requiredUnderlyingNetworkCapabilities,
            @NonNull UnderlyingNetworkTrackerCallback cb,
            @NonNull UnderlyingNetworkTrackerCallback cb,
            @NonNull Dependencies deps) {
            @NonNull Dependencies deps) {
        mVcnContext = Objects.requireNonNull(vcnContext, "Missing vcnContext");
        mVcnContext = Objects.requireNonNull(vcnContext, "Missing vcnContext");
        mSubscriptionGroup = Objects.requireNonNull(subscriptionGroup, "Missing subscriptionGroup");
        mSubscriptionGroup = Objects.requireNonNull(subscriptionGroup, "Missing subscriptionGroup");
        mLastSnapshot = Objects.requireNonNull(snapshot, "Missing snapshot");
        mRequiredUnderlyingNetworkCapabilities =
        mRequiredUnderlyingNetworkCapabilities =
                Objects.requireNonNull(
                Objects.requireNonNull(
                        requiredUnderlyingNetworkCapabilities,
                        requiredUnderlyingNetworkCapabilities,
@@ -103,7 +105,6 @@ public class UnderlyingNetworkTracker {
        mHandler = new Handler(mVcnContext.getLooper());
        mHandler = new Handler(mVcnContext.getLooper());


        mConnectivityManager = mVcnContext.getContext().getSystemService(ConnectivityManager.class);
        mConnectivityManager = mVcnContext.getContext().getSystemService(ConnectivityManager.class);
        mSubscriptionManager = mVcnContext.getContext().getSystemService(SubscriptionManager.class);


        registerNetworkRequests();
        registerNetworkRequests();
    }
    }
@@ -149,34 +150,47 @@ public class UnderlyingNetworkTracker {
    private void updateSubIdsAndCellularRequests() {
    private void updateSubIdsAndCellularRequests() {
        mVcnContext.ensureRunningOnLooperThread();
        mVcnContext.ensureRunningOnLooperThread();


        Set<Integer> prevSubIds = new ArraySet<>(mSubIds);
        // Don't bother re-filing NetworkRequests if this Tracker has been torn down.
        mSubIds.clear();
        if (!mIsRunning) {
            return;
        }

        final Set<Integer> subIdsInSubGroup = mLastSnapshot.getAllSubIdsInGroup(mSubscriptionGroup);


        // Ensure NetworkRequests filed for all current subIds in mSubscriptionGroup
        // new subIds to track = (updated list of subIds) - (currently tracked subIds)
        // STOPSHIP: b/177364490 use TelephonySubscriptionSnapshot to avoid querying Telephony
        final Set<Integer> subIdsToRegister = new ArraySet<>(subIdsInSubGroup);
        List<SubscriptionInfo> subInfos =
        subIdsToRegister.removeAll(mCellBringupCallbacks.keySet());
                mSubscriptionManager.getSubscriptionsInGroup(mSubscriptionGroup);


        for (SubscriptionInfo subInfo : subInfos) {
        // subIds to stop tracking = (currently tracked subIds) - (updated list of subIds)
            final int subId = subInfo.getSubscriptionId();
        final Set<Integer> subIdsToUnregister = new ArraySet<>(mCellBringupCallbacks.keySet());
            mSubIds.add(subId);
        subIdsToUnregister.removeAll(subIdsInSubGroup);


            if (!mCellBringupCallbacks.contains(subId)) {
        for (final int subId : subIdsToRegister) {
            final NetworkBringupCallback cb = new NetworkBringupCallback();
            final NetworkBringupCallback cb = new NetworkBringupCallback();
            mCellBringupCallbacks.put(subId, cb);
            mCellBringupCallbacks.put(subId, cb);


            mConnectivityManager.requestBackgroundNetwork(
            mConnectivityManager.requestBackgroundNetwork(
                    getCellNetworkRequestForSubId(subId), mHandler, cb);
                    getCellNetworkRequestForSubId(subId), mHandler, cb);
        }
        }
        }


        // unregister all NetworkCallbacks for outdated subIds
        for (final int subId : subIdsToUnregister) {
        for (final int subId : prevSubIds) {
            final NetworkCallback cb = mCellBringupCallbacks.remove(subId);
            if (!mSubIds.contains(subId)) {
                final NetworkCallback cb = mCellBringupCallbacks.removeReturnOld(subId);
            mConnectivityManager.unregisterNetworkCallback(cb);
            mConnectivityManager.unregisterNetworkCallback(cb);
        }
        }
    }
    }

    /**
     * Update this UnderlyingNetworkTracker's TelephonySubscriptionSnapshot.
     *
     * <p>Updating the TelephonySubscriptionSnapshot will cause this UnderlyingNetworkTracker to
     * reevaluate its NetworkBringupCallbacks. This may result in NetworkRequests being registered
     * or unregistered if the subIds mapped to the this Tracker's SubscriptionGroup change.
     */
    public void updateSubscriptionSnapshot(@NonNull TelephonySubscriptionSnapshot snapshot) {
        Objects.requireNonNull(snapshot, "Missing snapshot");

        mLastSnapshot = snapshot;
        updateSubIdsAndCellularRequests();
    }
    }


    /** Tears down this Tracker, and releases all underlying network requests. */
    /** Tears down this Tracker, and releases all underlying network requests. */
@@ -186,11 +200,12 @@ public class UnderlyingNetworkTracker {
        mConnectivityManager.unregisterNetworkCallback(mWifiBringupCallback);
        mConnectivityManager.unregisterNetworkCallback(mWifiBringupCallback);
        mConnectivityManager.unregisterNetworkCallback(mRouteSelectionCallback);
        mConnectivityManager.unregisterNetworkCallback(mRouteSelectionCallback);


        for (final int subId : mSubIds) {
        for (final NetworkCallback cb : mCellBringupCallbacks.values()) {
            final NetworkCallback cb = mCellBringupCallbacks.removeReturnOld(subId);
            mConnectivityManager.unregisterNetworkCallback(cb);
            mConnectivityManager.unregisterNetworkCallback(cb);
        }
        }
        mSubIds.clear();
        mCellBringupCallbacks.clear();

        mIsRunning = false;
    }
    }


    /** Returns whether the currently selected Network matches the given network. */
    /** Returns whether the currently selected Network matches the given network. */
+68 −6
Original line number Original line Diff line number Diff line
@@ -27,9 +27,16 @@ import android.os.Message;
import android.os.ParcelUuid;
import android.os.ParcelUuid;
import android.util.Slog;
import android.util.Slog;


import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting.Visibility;
import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map;
import java.util.Objects;
import java.util.Objects;
import java.util.Set;


/**
/**
 * Represents an single instance of a VCN.
 * Represents an single instance of a VCN.
@@ -63,6 +70,15 @@ public class Vcn extends Handler {
     */
     */
    private static final int MSG_EVENT_NETWORK_REQUESTED = MSG_EVENT_BASE + 1;
    private static final int MSG_EVENT_NETWORK_REQUESTED = MSG_EVENT_BASE + 1;


    /**
     * The TelephonySubscriptionSnapshot tracked by VcnManagementService has changed.
     *
     * <p>This updated snapshot should be cached locally and passed to all VcnGatewayConnections.
     *
     * @param obj TelephonySubscriptionSnapshot
     */
    private static final int MSG_EVENT_SUBSCRIPTIONS_CHANGED = MSG_EVENT_BASE + 2;

    /** Triggers an immediate teardown of the entire Vcn, including GatewayConnections. */
    /** Triggers an immediate teardown of the entire Vcn, including GatewayConnections. */
    private static final int MSG_CMD_TEARDOWN = MSG_CMD_BASE;
    private static final int MSG_CMD_TEARDOWN = MSG_CMD_BASE;


@@ -76,20 +92,24 @@ public class Vcn extends Handler {
            new HashMap<>();
            new HashMap<>();


    @NonNull private VcnConfig mConfig;
    @NonNull private VcnConfig mConfig;
    @NonNull private TelephonySubscriptionSnapshot mLastSnapshot;


    private boolean mIsRunning = true;
    private boolean mIsRunning = true;


    public Vcn(
    public Vcn(
            @NonNull VcnContext vcnContext,
            @NonNull VcnContext vcnContext,
            @NonNull ParcelUuid subscriptionGroup,
            @NonNull ParcelUuid subscriptionGroup,
            @NonNull VcnConfig config) {
            @NonNull VcnConfig config,
        this(vcnContext, subscriptionGroup, config, new Dependencies());
            @NonNull TelephonySubscriptionSnapshot snapshot) {
        this(vcnContext, subscriptionGroup, config, snapshot, new Dependencies());
    }
    }


    private Vcn(
    @VisibleForTesting(visibility = Visibility.PRIVATE)
    public Vcn(
            @NonNull VcnContext vcnContext,
            @NonNull VcnContext vcnContext,
            @NonNull ParcelUuid subscriptionGroup,
            @NonNull ParcelUuid subscriptionGroup,
            @NonNull VcnConfig config,
            @NonNull VcnConfig config,
            @NonNull TelephonySubscriptionSnapshot snapshot,
            @NonNull Dependencies deps) {
            @NonNull Dependencies deps) {
        super(Objects.requireNonNull(vcnContext, "Missing vcnContext").getLooper());
        super(Objects.requireNonNull(vcnContext, "Missing vcnContext").getLooper());
        mVcnContext = vcnContext;
        mVcnContext = vcnContext;
@@ -98,6 +118,7 @@ public class Vcn extends Handler {
        mRequestListener = new VcnNetworkRequestListener();
        mRequestListener = new VcnNetworkRequestListener();


        mConfig = Objects.requireNonNull(config, "Missing config");
        mConfig = Objects.requireNonNull(config, "Missing config");
        mLastSnapshot = Objects.requireNonNull(snapshot, "Missing snapshot");


        // Register to receive cached and future NetworkRequests
        // Register to receive cached and future NetworkRequests
        mVcnContext.getVcnNetworkProvider().registerListener(mRequestListener);
        mVcnContext.getVcnNetworkProvider().registerListener(mRequestListener);
@@ -110,11 +131,24 @@ public class Vcn extends Handler {
        sendMessage(obtainMessage(MSG_EVENT_CONFIG_UPDATED, config));
        sendMessage(obtainMessage(MSG_EVENT_CONFIG_UPDATED, config));
    }
    }


    /** Asynchronously updates the Subscription snapshot for this VCN. */
    public void updateSubscriptionSnapshot(@NonNull TelephonySubscriptionSnapshot snapshot) {
        Objects.requireNonNull(snapshot, "Missing snapshot");

        sendMessage(obtainMessage(MSG_EVENT_SUBSCRIPTIONS_CHANGED, snapshot));
    }

    /** Asynchronously tears down this Vcn instance, including VcnGatewayConnection(s) */
    /** Asynchronously tears down this Vcn instance, including VcnGatewayConnection(s) */
    public void teardownAsynchronously() {
    public void teardownAsynchronously() {
        sendMessageAtFrontOfQueue(obtainMessage(MSG_CMD_TEARDOWN));
        sendMessageAtFrontOfQueue(obtainMessage(MSG_CMD_TEARDOWN));
    }
    }


    /** Get current Gateways for testing purposes */
    @VisibleForTesting(visibility = Visibility.PRIVATE)
    public Set<VcnGatewayConnection> getVcnGatewayConnections() {
        return Collections.unmodifiableSet(new HashSet<>(mVcnGatewayConnections.values()));
    }

    private class VcnNetworkRequestListener implements VcnNetworkProvider.NetworkRequestListener {
    private class VcnNetworkRequestListener implements VcnNetworkProvider.NetworkRequestListener {
        @Override
        @Override
        public void onNetworkRequested(@NonNull NetworkRequest request, int score, int providerId) {
        public void onNetworkRequested(@NonNull NetworkRequest request, int score, int providerId) {
@@ -137,6 +171,9 @@ public class Vcn extends Handler {
            case MSG_EVENT_NETWORK_REQUESTED:
            case MSG_EVENT_NETWORK_REQUESTED:
                handleNetworkRequested((NetworkRequest) msg.obj, msg.arg1, msg.arg2);
                handleNetworkRequested((NetworkRequest) msg.obj, msg.arg1, msg.arg2);
                break;
                break;
            case MSG_EVENT_SUBSCRIPTIONS_CHANGED:
                handleSubscriptionsChanged((TelephonySubscriptionSnapshot) msg.obj);
                break;
            case MSG_CMD_TEARDOWN:
            case MSG_CMD_TEARDOWN:
                handleTeardown();
                handleTeardown();
                break;
                break;
@@ -192,13 +229,26 @@ public class Vcn extends Handler {
                        "Bringing up new VcnGatewayConnection for request " + request.requestId);
                        "Bringing up new VcnGatewayConnection for request " + request.requestId);


                final VcnGatewayConnection vcnGatewayConnection =
                final VcnGatewayConnection vcnGatewayConnection =
                        new VcnGatewayConnection(
                        mDeps.newVcnGatewayConnection(
                                mVcnContext, mSubscriptionGroup, gatewayConnectionConfig);
                                mVcnContext,
                                mSubscriptionGroup,
                                mLastSnapshot,
                                gatewayConnectionConfig);
                mVcnGatewayConnections.put(gatewayConnectionConfig, vcnGatewayConnection);
                mVcnGatewayConnections.put(gatewayConnectionConfig, vcnGatewayConnection);
            }
            }
        }
        }
    }
    }


    private void handleSubscriptionsChanged(@NonNull TelephonySubscriptionSnapshot snapshot) {
        mLastSnapshot = snapshot;

        if (mIsRunning) {
            for (VcnGatewayConnection gatewayConnection : mVcnGatewayConnections.values()) {
                gatewayConnection.updateSubscriptionSnapshot(mLastSnapshot);
            }
        }
    }

    private boolean requestSatisfiedByGatewayConnectionConfig(
    private boolean requestSatisfiedByGatewayConnectionConfig(
            @NonNull NetworkRequest request, @NonNull VcnGatewayConnectionConfig config) {
            @NonNull NetworkRequest request, @NonNull VcnGatewayConnectionConfig config) {
        final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder();
        final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder();
@@ -221,5 +271,17 @@ public class Vcn extends Handler {
        return 52;
        return 52;
    }
    }


    private static class Dependencies {}
    /** External dependencies used by Vcn, for injection in tests */
    @VisibleForTesting(visibility = Visibility.PRIVATE)
    public static class Dependencies {
        /** Builds a new VcnGatewayConnection */
        public VcnGatewayConnection newVcnGatewayConnection(
                VcnContext vcnContext,
                ParcelUuid subscriptionGroup,
                TelephonySubscriptionSnapshot snapshot,
                VcnGatewayConnectionConfig connectionConfig) {
            return new VcnGatewayConnection(
                    vcnContext, subscriptionGroup, snapshot, connectionConfig);
        }
    }
}
}
+52 −3
Original line number Original line Diff line number Diff line
@@ -61,10 +61,12 @@ import android.os.ParcelUuid;
import android.util.ArraySet;
import android.util.ArraySet;
import android.util.Slog;
import android.util.Slog;


import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting.Visibility;
import com.android.internal.annotations.VisibleForTesting.Visibility;
import com.android.internal.util.State;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import com.android.internal.util.StateMachine;
import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
import com.android.server.vcn.UnderlyingNetworkTracker.UnderlyingNetworkRecord;
import com.android.server.vcn.UnderlyingNetworkTracker.UnderlyingNetworkRecord;
import com.android.server.vcn.UnderlyingNetworkTracker.UnderlyingNetworkTrackerCallback;
import com.android.server.vcn.UnderlyingNetworkTracker.UnderlyingNetworkTrackerCallback;


@@ -371,6 +373,16 @@ public class VcnGatewayConnection extends StateMachine {
     */
     */
    private static final int EVENT_TEARDOWN_TIMEOUT_EXPIRED = 8;
    private static final int EVENT_TEARDOWN_TIMEOUT_EXPIRED = 8;


    /**
     * Sent when this VcnGatewayConnection is notified of a change in TelephonySubscriptions.
     *
     * <p>Relevant in all states.
     *
     * @param arg1 The "all" token; this signal is always honored.
     */
    // TODO(b/178426520): implement handling of this event
    private static final int EVENT_SUBSCRIPTIONS_CHANGED = 9;

    @VisibleForTesting(visibility = Visibility.PRIVATE)
    @VisibleForTesting(visibility = Visibility.PRIVATE)
    @NonNull
    @NonNull
    final DisconnectedState mDisconnectedState = new DisconnectedState();
    final DisconnectedState mDisconnectedState = new DisconnectedState();
@@ -391,6 +403,11 @@ public class VcnGatewayConnection extends StateMachine {
    @NonNull
    @NonNull
    final RetryTimeoutState mRetryTimeoutState = new RetryTimeoutState();
    final RetryTimeoutState mRetryTimeoutState = new RetryTimeoutState();


    @NonNull private final Object mLock = new Object();

    @GuardedBy("mLock")
    @NonNull private TelephonySubscriptionSnapshot mLastSnapshot;

    @NonNull private final VcnContext mVcnContext;
    @NonNull private final VcnContext mVcnContext;
    @NonNull private final ParcelUuid mSubscriptionGroup;
    @NonNull private final ParcelUuid mSubscriptionGroup;
    @NonNull private final UnderlyingNetworkTracker mUnderlyingNetworkTracker;
    @NonNull private final UnderlyingNetworkTracker mUnderlyingNetworkTracker;
@@ -469,14 +486,16 @@ public class VcnGatewayConnection extends StateMachine {
    public VcnGatewayConnection(
    public VcnGatewayConnection(
            @NonNull VcnContext vcnContext,
            @NonNull VcnContext vcnContext,
            @NonNull ParcelUuid subscriptionGroup,
            @NonNull ParcelUuid subscriptionGroup,
            @NonNull TelephonySubscriptionSnapshot snapshot,
            @NonNull VcnGatewayConnectionConfig connectionConfig) {
            @NonNull VcnGatewayConnectionConfig connectionConfig) {
        this(vcnContext, subscriptionGroup, connectionConfig, new Dependencies());
        this(vcnContext, subscriptionGroup, snapshot, connectionConfig, new Dependencies());
    }
    }


    @VisibleForTesting(visibility = Visibility.PRIVATE)
    @VisibleForTesting(visibility = Visibility.PRIVATE)
    VcnGatewayConnection(
    VcnGatewayConnection(
            @NonNull VcnContext vcnContext,
            @NonNull VcnContext vcnContext,
            @NonNull ParcelUuid subscriptionGroup,
            @NonNull ParcelUuid subscriptionGroup,
            @NonNull TelephonySubscriptionSnapshot snapshot,
            @NonNull VcnGatewayConnectionConfig connectionConfig,
            @NonNull VcnGatewayConnectionConfig connectionConfig,
            @NonNull Dependencies deps) {
            @NonNull Dependencies deps) {
        super(TAG, Objects.requireNonNull(vcnContext, "Missing vcnContext").getLooper());
        super(TAG, Objects.requireNonNull(vcnContext, "Missing vcnContext").getLooper());
@@ -485,12 +504,17 @@ public class VcnGatewayConnection extends StateMachine {
        mConnectionConfig = Objects.requireNonNull(connectionConfig, "Missing connectionConfig");
        mConnectionConfig = Objects.requireNonNull(connectionConfig, "Missing connectionConfig");
        mDeps = Objects.requireNonNull(deps, "Missing deps");
        mDeps = Objects.requireNonNull(deps, "Missing deps");


        synchronized (mLock) {
            mLastSnapshot = Objects.requireNonNull(snapshot, "Missing snapshot");
        }

        mUnderlyingNetworkTrackerCallback = new VcnUnderlyingNetworkTrackerCallback();
        mUnderlyingNetworkTrackerCallback = new VcnUnderlyingNetworkTrackerCallback();


        mUnderlyingNetworkTracker =
        mUnderlyingNetworkTracker =
                mDeps.newUnderlyingNetworkTracker(
                mDeps.newUnderlyingNetworkTracker(
                        mVcnContext,
                        mVcnContext,
                        subscriptionGroup,
                        subscriptionGroup,
                        mLastSnapshot,
                        mConnectionConfig.getAllUnderlyingCapabilities(),
                        mConnectionConfig.getAllUnderlyingCapabilities(),
                        mUnderlyingNetworkTrackerCallback);
                        mUnderlyingNetworkTrackerCallback);
        mIpSecManager = mVcnContext.getContext().getSystemService(IpSecManager.class);
        mIpSecManager = mVcnContext.getContext().getSystemService(IpSecManager.class);
@@ -545,6 +569,25 @@ public class VcnGatewayConnection extends StateMachine {
        mUnderlyingNetworkTracker.teardown();
        mUnderlyingNetworkTracker.teardown();
    }
    }


    /**
     * Notify this Gateway that subscriptions have changed.
     *
     * <p>This snapshot should be used to update any keepalive requests necessary for potential
     * underlying Networks in this Gateway's subscription group.
     */
    public void updateSubscriptionSnapshot(@NonNull TelephonySubscriptionSnapshot snapshot) {
        Objects.requireNonNull(snapshot, "Missing snapshot");

        // Vcn is the only user of this method and runs on the same Thread, but lock around
        // mLastSnapshot to be technically correct.
        synchronized (mLock) {
            mLastSnapshot = snapshot;
            mUnderlyingNetworkTracker.updateSubscriptionSnapshot(mLastSnapshot);
        }

        sendMessage(EVENT_SUBSCRIPTIONS_CHANGED, TOKEN_ALL);
    }

    private class VcnUnderlyingNetworkTrackerCallback implements UnderlyingNetworkTrackerCallback {
    private class VcnUnderlyingNetworkTrackerCallback implements UnderlyingNetworkTrackerCallback {
        @Override
        @Override
        public void onSelectedUnderlyingNetworkChanged(
        public void onSelectedUnderlyingNetworkChanged(
@@ -682,7 +725,8 @@ public class VcnGatewayConnection extends StateMachine {
                case EVENT_TRANSFORM_CREATED: // Fallthrough
                case EVENT_TRANSFORM_CREATED: // Fallthrough
                case EVENT_SETUP_COMPLETED: // Fallthrough
                case EVENT_SETUP_COMPLETED: // Fallthrough
                case EVENT_DISCONNECT_REQUESTED: // Fallthrough
                case EVENT_DISCONNECT_REQUESTED: // Fallthrough
                case EVENT_TEARDOWN_TIMEOUT_EXPIRED:
                case EVENT_TEARDOWN_TIMEOUT_EXPIRED: // Fallthrough
                case EVENT_SUBSCRIPTIONS_CHANGED:
                    logUnexpectedEvent(msg.what);
                    logUnexpectedEvent(msg.what);
                    break;
                    break;
                default:
                default:
@@ -1384,10 +1428,15 @@ public class VcnGatewayConnection extends StateMachine {
        public UnderlyingNetworkTracker newUnderlyingNetworkTracker(
        public UnderlyingNetworkTracker newUnderlyingNetworkTracker(
                VcnContext vcnContext,
                VcnContext vcnContext,
                ParcelUuid subscriptionGroup,
                ParcelUuid subscriptionGroup,
                TelephonySubscriptionSnapshot snapshot,
                Set<Integer> requiredUnderlyingNetworkCapabilities,
                Set<Integer> requiredUnderlyingNetworkCapabilities,
                UnderlyingNetworkTrackerCallback callback) {
                UnderlyingNetworkTrackerCallback callback) {
            return new UnderlyingNetworkTracker(
            return new UnderlyingNetworkTracker(
                    vcnContext, subscriptionGroup, requiredUnderlyingNetworkCapabilities, callback);
                    vcnContext,
                    subscriptionGroup,
                    snapshot,
                    requiredUnderlyingNetworkCapabilities,
                    callback);
        }
        }


        /** Builds a new IkeSession. */
        /** Builds a new IkeSession. */
+13 −4
Original line number Original line Diff line number Diff line
@@ -25,6 +25,9 @@ import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.ArraySet;
import android.util.Slog;
import android.util.Slog;


import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting.Visibility;

import java.util.Objects;
import java.util.Objects;
import java.util.Set;
import java.util.Set;


@@ -52,8 +55,13 @@ public class VcnNetworkProvider extends NetworkProvider {
        super(context, looper, VcnNetworkProvider.class.getSimpleName());
        super(context, looper, VcnNetworkProvider.class.getSimpleName());
    }
    }


    // Package-private
    /**
    void registerListener(@NonNull NetworkRequestListener listener) {
     * Registers a NetworkRequestListener with this NetworkProvider.
     *
     * <p>Upon registering, the provided listener will receive all cached requests.
     */
    @VisibleForTesting(visibility = Visibility.PACKAGE)
    public void registerListener(@NonNull NetworkRequestListener listener) {
        mListeners.add(listener);
        mListeners.add(listener);


        // Send listener all cached requests
        // Send listener all cached requests
@@ -62,8 +70,9 @@ public class VcnNetworkProvider extends NetworkProvider {
        }
        }
    }
    }


    // Package-private
    /** Unregisters the specified listener from receiving future NetworkRequests. */
    void unregisterListener(@NonNull NetworkRequestListener listener) {
    @VisibleForTesting(visibility = Visibility.PACKAGE)
    public void unregisterListener(@NonNull NetworkRequestListener listener) {
        mListeners.remove(listener);
        mListeners.remove(listener);
    }
    }


Loading