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

Commit 52629838 authored by Benedict Wong's avatar Benedict Wong
Browse files

Add CarrierConfig to TelephonySubscriptionSnapshot

This change ensures that carrier configs are saved as part of the
snapshot, allowing all entities in the VCN to query telephony
subscription information from the same source.

Test: atest FrameworksVcnTests
Change-Id: I31447d84fe98d6bd2cc78ead41746198728c400b
parent 1428215b
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -104,6 +104,14 @@ public class VcnManager {

    // TODO: Add separate signal strength thresholds for 2.4 GHz and 5GHz

    /** List of Carrier Config options to extract from Carrier Config bundles. @hide */
    @NonNull
    public static final String[] VCN_RELATED_CARRIER_CONFIG_KEYS =
            new String[] {
                VCN_NETWORK_SELECTION_WIFI_ENTRY_RSSI_THRESHOLD_KEY,
                VCN_NETWORK_SELECTION_WIFI_EXIT_RSSI_THRESHOLD_KEY
            };

    private static final Map<
                    VcnNetworkPolicyChangeListener, VcnUnderlyingNetworkPolicyListenerBinder>
            REGISTERED_POLICY_LISTENERS = new ConcurrentHashMap<>();
+80 −6
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.vcn.VcnManager;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.ParcelUuid;
@@ -47,6 +48,8 @@ import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting.Visibility;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.vcn.util.PersistableBundleUtils;
import com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;

import java.util.ArrayList;
import java.util.Collections;
@@ -95,6 +98,10 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {

    // TODO (Android T+): Add ability to handle multiple subIds per slot.
    @NonNull private final Map<Integer, Integer> mReadySubIdsBySlotId = new HashMap<>();

    @NonNull
    private final Map<Integer, PersistableBundleWrapper> mSubIdToCarrierConfigMap = new HashMap<>();

    @NonNull private final OnSubscriptionsChangedListener mSubscriptionChangedListener;

    @NonNull
@@ -250,7 +257,10 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {

        final TelephonySubscriptionSnapshot newSnapshot =
                new TelephonySubscriptionSnapshot(
                        mDeps.getActiveDataSubscriptionId(), newSubIdToInfoMap, privilegedPackages);
                        mDeps.getActiveDataSubscriptionId(),
                        newSubIdToInfoMap,
                        mSubIdToCarrierConfigMap,
                        privilegedPackages);

        // If snapshot was meaningfully updated, fire the callback
        if (!newSnapshot.equals(mCurrentSnapshot)) {
@@ -311,47 +321,77 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
        }

        if (SubscriptionManager.isValidSubscriptionId(subId)) {
            final PersistableBundle carrierConfigs = mCarrierConfigManager.getConfigForSubId(subId);
            if (mDeps.isConfigForIdentifiedCarrier(carrierConfigs)) {
            final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId);
            if (mDeps.isConfigForIdentifiedCarrier(carrierConfig)) {
                mReadySubIdsBySlotId.put(slotId, subId);

                final PersistableBundle minimized =
                        PersistableBundleUtils.minimizeBundle(
                                carrierConfig, VcnManager.VCN_RELATED_CARRIER_CONFIG_KEYS);
                if (minimized != null) {
                    mSubIdToCarrierConfigMap.put(subId, new PersistableBundleWrapper(minimized));
                }
                handleSubscriptionsChanged();
            }
        } else {
            mReadySubIdsBySlotId.remove(slotId);
            final Integer oldSubid = mReadySubIdsBySlotId.remove(slotId);
            if (oldSubid != null) {
                mSubIdToCarrierConfigMap.remove(oldSubid);
            }
            handleSubscriptionsChanged();
        }
    }

    @VisibleForTesting(visibility = Visibility.PRIVATE)
    void setReadySubIdsBySlotId(Map<Integer, Integer> readySubIdsBySlotId) {
        mReadySubIdsBySlotId.clear();
        mReadySubIdsBySlotId.putAll(readySubIdsBySlotId);
    }

    @VisibleForTesting(visibility = Visibility.PRIVATE)
    void setSubIdToCarrierConfigMap(
            Map<Integer, PersistableBundleWrapper> subIdToCarrierConfigMap) {
        mSubIdToCarrierConfigMap.clear();
        mSubIdToCarrierConfigMap.putAll(subIdToCarrierConfigMap);
    }

    @VisibleForTesting(visibility = Visibility.PRIVATE)
    Map<Integer, Integer> getReadySubIdsBySlotId() {
        return Collections.unmodifiableMap(mReadySubIdsBySlotId);
    }

    @VisibleForTesting(visibility = Visibility.PRIVATE)
    Map<Integer, PersistableBundleWrapper> getSubIdToCarrierConfigMap() {
        return Collections.unmodifiableMap(mSubIdToCarrierConfigMap);
    }

    /** TelephonySubscriptionSnapshot is a class containing info about active subscriptions */
    public static class TelephonySubscriptionSnapshot {
        private final int mActiveDataSubId;
        private final Map<Integer, SubscriptionInfo> mSubIdToInfoMap;
        private final Map<Integer, PersistableBundleWrapper> mSubIdToCarrierConfigMap;
        private final Map<ParcelUuid, Set<String>> mPrivilegedPackages;

        public static final TelephonySubscriptionSnapshot EMPTY_SNAPSHOT =
                new TelephonySubscriptionSnapshot(
                        INVALID_SUBSCRIPTION_ID, Collections.emptyMap(), Collections.emptyMap());
                        INVALID_SUBSCRIPTION_ID,
                        Collections.emptyMap(),
                        Collections.emptyMap(),
                        Collections.emptyMap());

        @VisibleForTesting(visibility = Visibility.PRIVATE)
        TelephonySubscriptionSnapshot(
                int activeDataSubId,
                @NonNull Map<Integer, SubscriptionInfo> subIdToInfoMap,
                @NonNull Map<Integer, PersistableBundleWrapper> subIdToCarrierConfigMap,
                @NonNull Map<ParcelUuid, Set<String>> privilegedPackages) {
            mActiveDataSubId = activeDataSubId;
            Objects.requireNonNull(subIdToInfoMap, "subIdToInfoMap was null");
            Objects.requireNonNull(privilegedPackages, "privilegedPackages was null");
            Objects.requireNonNull(subIdToCarrierConfigMap, "subIdToCarrierConfigMap was null");

            mSubIdToInfoMap = Collections.unmodifiableMap(subIdToInfoMap);
            mSubIdToCarrierConfigMap = Collections.unmodifiableMap(subIdToCarrierConfigMap);

            final Map<ParcelUuid, Set<String>> unmodifiableInnerSets = new ArrayMap<>();
            for (Entry<ParcelUuid, Set<String>> entry : privilegedPackages.entrySet()) {
@@ -423,9 +463,40 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
                    : false;
        }

        /**
         * Retrieves a carrier config for a subscription in the provided group.
         *
         * <p>This method will prioritize non-opportunistic subscriptions, but will use the a
         * carrier config for an opportunistic subscription if no other subscriptions are found.
         */
        @Nullable
        public PersistableBundleWrapper getCarrierConfigForSubGrp(@NonNull ParcelUuid subGrp) {
            PersistableBundleWrapper result = null;

            for (int subId : getAllSubIdsInGroup(subGrp)) {
                final PersistableBundleWrapper config = mSubIdToCarrierConfigMap.get(subId);
                if (config != null) {
                    result = config;

                    // Attempt to use (any) non-opportunistic subscription. If this subscription is
                    // opportunistic, continue and try to find a non-opportunistic subscription,
                    // using the opportunistic ones as a last resort.
                    if (!isOpportunistic(subId)) {
                        return config;
                    }
                }
            }

            return result;
        }

        @Override
        public int hashCode() {
            return Objects.hash(mActiveDataSubId, mSubIdToInfoMap, mPrivilegedPackages);
            return Objects.hash(
                    mActiveDataSubId,
                    mSubIdToInfoMap,
                    mSubIdToCarrierConfigMap,
                    mPrivilegedPackages);
        }

        @Override
@@ -438,6 +509,7 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {

            return mActiveDataSubId == other.mActiveDataSubId
                    && mSubIdToInfoMap.equals(other.mSubIdToInfoMap)
                    && mSubIdToCarrierConfigMap.equals(other.mSubIdToCarrierConfigMap)
                    && mPrivilegedPackages.equals(other.mPrivilegedPackages);
        }

@@ -448,6 +520,7 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {

            pw.println("mActiveDataSubId: " + mActiveDataSubId);
            pw.println("mSubIdToInfoMap: " + mSubIdToInfoMap);
            pw.println("mSubIdToCarrierConfigMap: " + mSubIdToCarrierConfigMap);
            pw.println("mPrivilegedPackages: " + mPrivilegedPackages);

            pw.decreaseIndent();
@@ -458,6 +531,7 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
            return "TelephonySubscriptionSnapshot{ "
                    + "mActiveDataSubId=" + mActiveDataSubId
                    + ", mSubIdToInfoMap=" + mSubIdToInfoMap
                    + ", mSubIdToCarrierConfigMap=" + mSubIdToCarrierConfigMap
                    + ", mPrivilegedPackages=" + mPrivilegedPackages
                    + " }";
        }
+7 −7
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_FORBIDDEN;
import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_REQUIRED;

import static com.android.server.VcnManagementService.LOCAL_LOG;
import static com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;

import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -34,7 +35,6 @@ import android.net.vcn.VcnManager;
import android.net.vcn.VcnUnderlyingNetworkTemplate;
import android.net.vcn.VcnWifiUnderlyingNetworkTemplate;
import android.os.ParcelUuid;
import android.os.PersistableBundle;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Slog;
@@ -81,7 +81,7 @@ class NetworkPriorityClassifier {
            ParcelUuid subscriptionGroup,
            TelephonySubscriptionSnapshot snapshot,
            UnderlyingNetworkRecord currentlySelected,
            PersistableBundle carrierConfig) {
            PersistableBundleWrapper carrierConfig) {
        // mRouteSelectionNetworkRequest requires a network be both VALIDATED and NOT_SUSPENDED

        if (networkRecord.isBlocked) {
@@ -119,7 +119,7 @@ class NetworkPriorityClassifier {
            ParcelUuid subscriptionGroup,
            TelephonySubscriptionSnapshot snapshot,
            UnderlyingNetworkRecord currentlySelected,
            PersistableBundle carrierConfig) {
            PersistableBundleWrapper carrierConfig) {
        final NetworkCapabilities caps = networkRecord.networkCapabilities;
        final boolean isSelectedUnderlyingNetwork =
                currentlySelected != null
@@ -181,7 +181,7 @@ class NetworkPriorityClassifier {
            VcnWifiUnderlyingNetworkTemplate networkPriority,
            UnderlyingNetworkRecord networkRecord,
            UnderlyingNetworkRecord currentlySelected,
            PersistableBundle carrierConfig) {
            PersistableBundleWrapper carrierConfig) {
        final NetworkCapabilities caps = networkRecord.networkCapabilities;

        if (!caps.hasTransport(TRANSPORT_WIFI)) {
@@ -204,7 +204,7 @@ class NetworkPriorityClassifier {
    private static boolean isWifiRssiAcceptable(
            UnderlyingNetworkRecord networkRecord,
            UnderlyingNetworkRecord currentlySelected,
            PersistableBundle carrierConfig) {
            PersistableBundleWrapper carrierConfig) {
        final NetworkCapabilities caps = networkRecord.networkCapabilities;
        final boolean isSelectedNetwork =
                currentlySelected != null
@@ -314,7 +314,7 @@ class NetworkPriorityClassifier {
        return false;
    }

    static int getWifiEntryRssiThreshold(@Nullable PersistableBundle carrierConfig) {
    static int getWifiEntryRssiThreshold(@Nullable PersistableBundleWrapper carrierConfig) {
        if (carrierConfig != null) {
            return carrierConfig.getInt(
                    VcnManager.VCN_NETWORK_SELECTION_WIFI_ENTRY_RSSI_THRESHOLD_KEY,
@@ -323,7 +323,7 @@ class NetworkPriorityClassifier {
        return WIFI_ENTRY_RSSI_THRESHOLD_DEFAULT;
    }

    static int getWifiExitRssiThreshold(@Nullable PersistableBundle carrierConfig) {
    static int getWifiExitRssiThreshold(@Nullable PersistableBundleWrapper carrierConfig) {
        if (carrierConfig != null) {
            return carrierConfig.getInt(
                    VcnManager.VCN_NETWORK_SELECTION_WIFI_EXIT_RSSI_THRESHOLD_KEY,
+6 −24
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@ import static android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListen
import static com.android.server.VcnManagementService.LOCAL_LOG;
import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.getWifiEntryRssiThreshold;
import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.getWifiExitRssiThreshold;
import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.isOpportunistic;
import static com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;

import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -37,8 +37,6 @@ import android.net.vcn.VcnUnderlyingNetworkTemplate;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.ParcelUuid;
import android.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
import android.telephony.TelephonyCallback;
import android.telephony.TelephonyManager;
import android.util.ArrayMap;
@@ -51,7 +49,6 @@ import com.android.server.vcn.VcnContext;
import com.android.server.vcn.util.LogUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -87,7 +84,7 @@ public class UnderlyingNetworkController {
    @Nullable private UnderlyingNetworkListener mRouteSelectionCallback;

    @NonNull private TelephonySubscriptionSnapshot mLastSnapshot;
    @Nullable private PersistableBundle mCarrierConfig;
    @Nullable private PersistableBundleWrapper mCarrierConfig;
    private boolean mIsQuitting = false;

    @Nullable private UnderlyingNetworkRecord mCurrentRecord;
@@ -124,25 +121,7 @@ public class UnderlyingNetworkController {
                .getSystemService(TelephonyManager.class)
                .registerTelephonyCallback(new HandlerExecutor(mHandler), mActiveDataSubIdListener);

        // TODO: Listen for changes in carrier config that affect this.
        for (int subId : mLastSnapshot.getAllSubIdsInGroup(mSubscriptionGroup)) {
            PersistableBundle config =
                    mVcnContext
                            .getContext()
                            .getSystemService(CarrierConfigManager.class)
                            .getConfigForSubId(subId);

            if (config != null) {
                mCarrierConfig = config;

                // Attempt to use (any) non-opportunistic subscription. If this subscription is
                // opportunistic, continue and try to find a non-opportunistic subscription, using
                // the opportunistic ones as a last resort.
                if (!isOpportunistic(mLastSnapshot, Collections.singleton(subId))) {
                    break;
                }
            }
        }
        mCarrierConfig = mLastSnapshot.getCarrierConfigForSubGrp(mSubscriptionGroup);

        registerOrUpdateNetworkRequests();
    }
@@ -334,6 +313,9 @@ public class UnderlyingNetworkController {
        final TelephonySubscriptionSnapshot oldSnapshot = mLastSnapshot;
        mLastSnapshot = newSnapshot;

        // Update carrier config
        mCarrierConfig = mLastSnapshot.getCarrierConfigForSubGrp(mSubscriptionGroup);

        // Only trigger re-registration if subIds in this group have changed
        if (oldSnapshot
                .getAllSubIdsInGroup(mSubscriptionGroup)
+5 −4
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server.vcn.routeselection;

import static com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.net.LinkProperties;
@@ -23,7 +25,6 @@ import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.vcn.VcnUnderlyingNetworkTemplate;
import android.os.ParcelUuid;
import android.os.PersistableBundle;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting.Visibility;
@@ -68,7 +69,7 @@ public class UnderlyingNetworkRecord {
            ParcelUuid subscriptionGroup,
            TelephonySubscriptionSnapshot snapshot,
            UnderlyingNetworkRecord currentlySelected,
            PersistableBundle carrierConfig) {
            PersistableBundleWrapper carrierConfig) {
        // Never changes after the underlying network record is created.
        if (mPriorityClass == PRIORITY_CLASS_INVALID) {
            mPriorityClass =
@@ -113,7 +114,7 @@ public class UnderlyingNetworkRecord {
            ParcelUuid subscriptionGroup,
            TelephonySubscriptionSnapshot snapshot,
            UnderlyingNetworkRecord currentlySelected,
            PersistableBundle carrierConfig) {
            PersistableBundleWrapper carrierConfig) {
        return (left, right) -> {
            final int leftIndex =
                    left.getOrCalculatePriorityClass(
@@ -167,7 +168,7 @@ public class UnderlyingNetworkRecord {
            ParcelUuid subscriptionGroup,
            TelephonySubscriptionSnapshot snapshot,
            UnderlyingNetworkRecord currentlySelected,
            PersistableBundle carrierConfig) {
            PersistableBundleWrapper carrierConfig) {
        pw.println("UnderlyingNetworkRecord:");
        pw.increaseIndent();

Loading