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

Commit ba32d92a authored by Jack Yu's avatar Jack Yu Committed by Android (Google) Code Review
Browse files

Merge changes from topics "td_based_caps", "urllc_embb"

* changes:
  Supported URLLC, EMBB, and CBS slicing
  Supported traffic descriptor based network capability
parents 863ed014 f2dd7ecb
Loading
Loading
Loading
Loading
+48 −14
Original line number Diff line number Diff line
@@ -356,6 +356,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

@@ -1003,10 +1004,19 @@ public class RILUtils {
                .setUser(dpi.user)
                .setAlwaysOn(dpi.alwaysOn)
                .build();

        TrafficDescriptor td;
        try {
            td = convertHalTrafficDescriptor(dpi.trafficDescriptor);
        } catch (IllegalArgumentException e) {
            loge("convertToDataProfile: Failed to convert traffic descriptor. e=" + e);
            td = null;
        }

        return new DataProfile.Builder()
                .setType(dpi.type)
                .setPreferred(dpi.preferred)
                .setTrafficDescriptor(convertHalTrafficDescriptor(dpi.trafficDescriptor))
                .setTrafficDescriptor(td)
                .setApnSetting(apnSetting)
                .build();
    }
@@ -3480,8 +3490,13 @@ public class RILUtils {
            sliceInfo = result.sliceInfo.getDiscriminator()
                    == android.hardware.radio.V1_6.OptionalSliceInfo.hidl_discriminator.noinit
                    ? null : convertHalSliceInfo(result.sliceInfo.value());
            trafficDescriptors = result.trafficDescriptors.stream().map(
                    RILUtils::convertHalTrafficDescriptor).collect(Collectors.toList());
            for (android.hardware.radio.V1_6.TrafficDescriptor td : result.trafficDescriptors) {
                try {
                    trafficDescriptors.add(RILUtils.convertHalTrafficDescriptor(td));
                } catch (IllegalArgumentException e) {
                    loge("convertHalDataCallResult: Failed to convert traffic descriptor. e=" + e);
                }
            }
        } else {
            loge("Unsupported SetupDataCallResult " + dcResult);
            return null;
@@ -3614,7 +3629,11 @@ public class RILUtils {
        }
        List<TrafficDescriptor> trafficDescriptors = new ArrayList<>();
        for (android.hardware.radio.data.TrafficDescriptor td : result.trafficDescriptors) {
            try {
                trafficDescriptors.add(convertHalTrafficDescriptor(td));
            } catch (IllegalArgumentException e) {
                loge("convertHalDataCallResult: Failed to convert traffic descriptor. e=" + e);
            }
        }

        return new DataCallResponse.Builder()
@@ -3664,33 +3683,34 @@ public class RILUtils {
    }

    private static TrafficDescriptor convertHalTrafficDescriptor(
            android.hardware.radio.V1_6.TrafficDescriptor td) {
            android.hardware.radio.V1_6.TrafficDescriptor td) throws IllegalArgumentException {
        String dnn = td.dnn.getDiscriminator()
                == android.hardware.radio.V1_6.OptionalDnn.hidl_discriminator.noinit
                ? null : td.dnn.value();
        String osAppId = td.osAppId.getDiscriminator()
        byte[] osAppId = td.osAppId.getDiscriminator()
                == android.hardware.radio.V1_6.OptionalOsAppId.hidl_discriminator.noinit
                ? null : new String(arrayListToPrimitiveArray(td.osAppId.value().osAppId));
                ? null : arrayListToPrimitiveArray(td.osAppId.value().osAppId);

        TrafficDescriptor.Builder builder = new TrafficDescriptor.Builder();
        if (dnn != null) {
            builder.setDataNetworkName(dnn);
        }
        if (osAppId != null) {
            builder.setOsAppId(osAppId.getBytes());
            builder.setOsAppId(osAppId);
        }
        return builder.build();
    }

    private static TrafficDescriptor convertHalTrafficDescriptor(
            android.hardware.radio.data.TrafficDescriptor td) {
            android.hardware.radio.data.TrafficDescriptor td) throws IllegalArgumentException {
        String dnn = td.dnn;
        String osAppId = td.osAppId == null ? null : new String(td.osAppId.osAppId);
        byte[] osAppId = td.osAppId == null ? null : td.osAppId.osAppId;
        TrafficDescriptor.Builder builder = new TrafficDescriptor.Builder();
        if (dnn != null) {
            builder.setDataNetworkName(dnn);
        }
        if (osAppId != null) {
            builder.setOsAppId(osAppId.getBytes());
            builder.setOsAppId(osAppId);
        }
        return builder.build();
    }
@@ -3703,7 +3723,17 @@ public class RILUtils {
    public static NetworkSlicingConfig convertHalSlicingConfig(
            android.hardware.radio.V1_6.SlicingConfig sc) {
        List<UrspRule> urspRules = sc.urspRules.stream().map(ur -> new UrspRule(ur.precedence,
                ur.trafficDescriptors.stream().map(RILUtils::convertHalTrafficDescriptor)
                ur.trafficDescriptors.stream()
                        .map(td -> {
                            try {
                                return convertHalTrafficDescriptor(td);
                            } catch (IllegalArgumentException e) {
                                loge("convertHalSlicingConfig: Failed to convert traffic descriptor"
                                        + ". e=" + e);
                                return null;
                            }
                        })
                        .filter(Objects::nonNull)
                        .collect(Collectors.toList()),
                ur.routeSelectionDescriptor.stream().map(rsd -> new RouteSelectionDescriptor(
                        rsd.precedence, rsd.sessionType.value(), rsd.sscMode.value(),
@@ -3726,7 +3756,11 @@ public class RILUtils {
        for (android.hardware.radio.data.UrspRule ur : sc.urspRules) {
            List<TrafficDescriptor> tds = new ArrayList<>();
            for (android.hardware.radio.data.TrafficDescriptor td : ur.trafficDescriptors) {
                try {
                    tds.add(convertHalTrafficDescriptor(td));
                } catch (IllegalArgumentException e) {
                    loge("convertHalTrafficDescriptor: " + e);
                }
            }
            List<RouteSelectionDescriptor> rsds = new ArrayList<>();
            for (android.hardware.radio.data.RouteSelectionDescriptor rsd
@@ -4510,7 +4544,7 @@ public class RILUtils {

    /**
     * Convert List<UiccSlotMapping> list to SlotPortMapping[]
     * @param list List<UiccSlotMapping> of slots mapping
     * @param slotMapping List<UiccSlotMapping> of slots mapping
     * @return SlotPortMapping[] of slots mapping
     */
    public static android.hardware.radio.config.SlotPortMapping[] convertSimSlotsMapping(
+2 −3
Original line number Diff line number Diff line
@@ -696,10 +696,9 @@ public class AccessNetworksManager extends Handler {
    public @TransportType int getPreferredTransportByNetworkCapability(
            @NetCapability int networkCapability) {
        int apnType = DataUtils.networkCapabilityToApnType(networkCapability);
        // For non-APN type capabilities, always route to WWAN.
        if (apnType == ApnSetting.TYPE_NONE) {
            // The network capability can't be converted to APN type.
            throw new IllegalArgumentException("Illegal network capability "
                    + DataUtils.networkCapabilityToString(networkCapability) + " provided.");
            return AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
        }
        return getPreferredTransport(apnType);
    }
+40 −11
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ import android.telephony.data.DataServiceCallback;
import android.telephony.data.NetworkSliceInfo;
import android.telephony.data.QosBearerSession;
import android.telephony.data.TrafficDescriptor;
import android.telephony.data.TrafficDescriptor.OsAppId;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.IndentingPrintWriter;
@@ -93,6 +94,7 @@ import com.android.telephony.Rlog;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
@@ -440,6 +442,9 @@ public class DataNetwork extends StateMachine {
    /** The network capabilities of this data network. */
    private @NonNull NetworkCapabilities mNetworkCapabilities;

    /** The matched traffic descriptor returned from setup data call request. */
    private final @NonNull List<TrafficDescriptor> mTrafficDescriptors = new ArrayList<>();

    /** The link properties of this data network. */
    private @NonNull LinkProperties mLinkProperties;

@@ -1299,6 +1304,38 @@ public class DataNetwork extends StateMachine {
            }
        }

        // Extract network capabilities from the traffic descriptor.
        for (TrafficDescriptor trafficDescriptor : mTrafficDescriptors) {
            try {
                OsAppId osAppId = new OsAppId(trafficDescriptor.getOsAppId());
                if (!osAppId.getOsId().equals(OsAppId.ANDROID_OS_ID)) {
                    loge("Received non-Android OS id " + osAppId.getOsId());
                    continue;
                }
                int networkCapability = DataUtils.getNetworkCapabilityFromString(
                        osAppId.getAppId());
                switch (networkCapability) {
                    case NetworkCapabilities.NET_CAPABILITY_ENTERPRISE:
                        builder.addCapability(networkCapability);
                        // Enterprise is the only capability supporting differentiator.
                        if (networkCapability == NetworkCapabilities.NET_CAPABILITY_ENTERPRISE) {
                            builder.addEnterpriseId(osAppId.getDifferentiator());
                        }
                        break;
                    case NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY:
                    case NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH:
                    case NetworkCapabilities.NET_CAPABILITY_CBS:
                        builder.addCapability(networkCapability);
                        break;
                    default:
                        loge("Invalid app id " + osAppId.getAppId());
                }
            } catch (Exception e) {
                loge("Exception: " + e + ". Failed to create osAppId from "
                        + new BigInteger(1, trafficDescriptor.getOsAppId()).toString(16));
            }
        }

        // TODO: Support NET_CAPABILITY_NOT_METERED when non-restricted data is for unmetered use
        if (!meteredApn) {
            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
@@ -1383,17 +1420,6 @@ public class DataNetwork extends StateMachine {
        return mNetworkCapabilities;
    }

    /**
     * Get the capabilities that can be translated to APN types.
     *
     * @return The capabilities that can be translated to APN types.
     */
    public @NonNull @NetCapability Set<Integer> getApnTypesCapabilities() {
        return Arrays.stream(mNetworkCapabilities.getCapabilities()).boxed()
                .filter(cap -> DataUtils.networkCapabilityToApnType(cap) != ApnSetting.TYPE_NONE)
                .collect(Collectors.toSet());
    }

    /**
     * @return The link properties of this data network.
     */
@@ -1647,6 +1673,9 @@ public class DataNetwork extends StateMachine {

        mNetworkSliceInfo = response.getSliceInfo();

        mTrafficDescriptors.clear();
        mTrafficDescriptors.addAll(response.getTrafficDescriptors());

        mQosBearerSessions.clear();
        mQosBearerSessions.addAll(response.getQosBearerSessions());
        if (mQosCallbackTracker != null) {
+5 −3
Original line number Diff line number Diff line
@@ -1762,7 +1762,7 @@ public class DataNetworkController extends Handler {
        return new NetworkRequestList(mAllNetworkRequestList.stream()
                .filter(request -> request.getState()
                        == TelephonyNetworkRequest.REQUEST_STATE_UNSATISFIED)
                .filter(request -> dataProfile.canSatisfy(request.getCapabilities()))
                .filter(request -> request.canBeSatisfiedBy(dataProfile))
                .collect(Collectors.toList()));
    }

@@ -2507,13 +2507,15 @@ public class DataNetworkController extends Handler {
                    + TelephonyUtils.dataStateToString(mInternetDataNetworkState) + " to "
                    + TelephonyUtils.dataStateToString(dataNetworkState) + ".");
            // TODO: Create a new route to notify TelephonyRegistry.
            if (dataNetworkState == TelephonyManager.DATA_CONNECTED) {
            if (dataNetworkState == TelephonyManager.DATA_CONNECTED
                    && mInternetDataNetworkState == TelephonyManager.DATA_DISCONNECTED) {
                mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
                        () -> callback.onInternetDataNetworkConnected(
                                allConnectedInternetDataNetworks.stream()
                                        .map(DataNetwork::getDataProfile)
                                        .collect(Collectors.toList()))));
            } else if (dataNetworkState == TelephonyManager.DATA_DISCONNECTED) {
            } else if (dataNetworkState == TelephonyManager.DATA_DISCONNECTED
                    && mInternetDataNetworkState == TelephonyManager.DATA_CONNECTED) {
                mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
                        callback::onInternetDataNetworkDisconnected));
            } // TODO: Add suspended callback if needed.
+139 −22
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@ import android.os.Looper;
import android.os.Message;
import android.provider.Telephony;
import android.telephony.Annotation;
import android.telephony.Annotation.NetCapability;
import android.telephony.Annotation.NetworkType;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
@@ -43,7 +42,6 @@ import android.util.ArraySet;
import android.util.IndentingPrintWriter;
import android.util.LocalLog;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback;
import com.android.telephony.Rlog;
@@ -63,6 +61,8 @@ import java.util.stream.Collectors;
 * subscription.
 */
public class DataProfileManager extends Handler {
    private static final boolean VDBG = true;

    /** Event for data config updated. */
    private static final int EVENT_DATA_CONFIG_UPDATED = 1;

@@ -217,7 +217,6 @@ public class DataProfileManager extends Handler {
                if (apn != null) {
                    DataProfile dataProfile = new DataProfile.Builder()
                            .setApnSetting(apn)
                            // TODO: Support TD correctly once ENTERPRISE becomes an APN type.
                            .setTrafficDescriptor(new TrafficDescriptor(apn.getApnName(), null))
                            .setPreferred(false)
                            .build();
@@ -332,6 +331,7 @@ public class DataProfileManager extends Handler {
                .orElse(null);
        // Save the preferred data profile into database.
        setPreferredDataProfile(dataProfile);
        updateDataProfiles();
    }

    /**
@@ -505,16 +505,98 @@ public class DataProfileManager extends Handler {
     */
    public @Nullable DataProfile getDataProfileForNetworkRequest(
            @NonNull TelephonyNetworkRequest networkRequest, @NetworkType int networkType) {
        ApnSetting apnSetting = null;
        if (networkRequest.hasAttribute(TelephonyNetworkRequest
                .CAPABILITY_ATTRIBUTE_APN_SETTING)) {
            apnSetting = getApnSettingForNetworkRequest(networkRequest, networkType);
        }

        TrafficDescriptor.Builder trafficDescriptorBuilder = new TrafficDescriptor.Builder();
        if (networkRequest.hasAttribute(TelephonyNetworkRequest
                .CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_DNN)) {
            if (apnSetting != null) {
                trafficDescriptorBuilder.setDataNetworkName(apnSetting.getApnName());
            }
        }

        if (networkRequest.hasAttribute(
                TelephonyNetworkRequest.CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_OS_APP_ID)) {
            TrafficDescriptor.OsAppId osAppId = networkRequest.getOsAppId();
            if (osAppId != null) {
                trafficDescriptorBuilder.setOsAppId(osAppId.getBytes());
            }
        }

        TrafficDescriptor trafficDescriptor;
        try {
            trafficDescriptor = trafficDescriptorBuilder.build();
        } catch (IllegalArgumentException e) {
            // We reach here when both ApnSetting and trafficDescriptor are null.
            log("Unable to find a data profile for " + networkRequest);
            return null;
        }

        // Instead of building the data profile from APN setting and traffic descriptor on-the-fly,
        // find the existing one from mAllDataProfiles so the last-setup timestamp can be retained.
        // Only create a new one when it can't be found.
        for (DataProfile dataProfile : mAllDataProfiles) {
            if (Objects.equals(apnSetting, dataProfile.getApnSetting())
                    && trafficDescriptor.equals(dataProfile.getTrafficDescriptor())) {
                return dataProfile;
            }
        }

        // When reaching here, it means that we have a valid non-null traffic descriptor, but
        // could not find it in mAllDataProfiles. This could happen on the traffic descriptor
        // capable capabilities like ENTERPRISE.
        DataProfile.Builder profileBuilder = new DataProfile.Builder();
        if (apnSetting != null) {
            profileBuilder.setApnSetting(apnSetting);
        }

        // trafficDescriptor is always non-null when we reach here.
        profileBuilder.setTrafficDescriptor(trafficDescriptor);

        DataProfile dataProfile = profileBuilder.build();
        log("Added a new data profile " + dataProfile + " for " + networkRequest);
        mAllDataProfiles.add(dataProfile);
        return dataProfile;
    }

    /**
     * Get the APN setting for the network request.
     *
     * @param networkRequest The network request.
     * @param networkType The current data network type.
     * @return The APN setting. {@code null} if can't find any satisfiable data profile.
     */
    private @Nullable ApnSetting getApnSettingForNetworkRequest(
            @NonNull TelephonyNetworkRequest networkRequest, @NetworkType int networkType) {
        if (!networkRequest.hasAttribute(
                TelephonyNetworkRequest.CAPABILITY_ATTRIBUTE_APN_SETTING)) {
            return null;
        }

        // Filter out the data profile that can't satisfy the request.
        // Preferred data profile should be returned in the top of the list.
        List<DataProfile> dataProfiles = getDataProfilesForNetworkCapabilities(
                networkRequest.getCapabilities());
        List<DataProfile> dataProfiles = mAllDataProfiles.stream()
                .filter(networkRequest::canBeSatisfiedBy)
                // Put the preferred data profile at the top of the list, then the longest time
                // hasn't used data profile will be in the front so all the data profiles can be
                // tried.
                .sorted(Comparator.comparing((DataProfile dp) -> !dp.equals(mPreferredDataProfile))
                        .thenComparingLong(DataProfile::getLastSetupTimestamp))
                .collect(Collectors.toList());
        for (DataProfile dataProfile : dataProfiles) {
            logv("Satisfied profile: " + dataProfile + ", last setup="
                    + DataUtils.elapsedTimeToString(dataProfile.getLastSetupTimestamp()));
        }
        if (dataProfiles.size() == 0) {
            log("Can't find any data profile that can satisfy " + networkRequest);
            return null;
        }

        // Step 3: Check if the remaining data profiles can used in current data network type.
        // Check if the remaining data profiles can used in current data network type.
        dataProfiles = dataProfiles.stream()
                .filter(dp -> dp.getApnSetting() != null
                        && dp.getApnSetting().canSupportNetworkType(networkType))
@@ -525,7 +607,7 @@ public class DataProfileManager extends Handler {
            return null;
        }

        // Step 4: Check if preferred data profile set id matches.
        // Check if preferred data profile set id matches.
        dataProfiles = dataProfiles.stream()
                .filter(dp -> dp.getApnSetting() != null
                        && (dp.getApnSetting().getApnSetId()
@@ -538,26 +620,53 @@ public class DataProfileManager extends Handler {
            return null;
        }

        return dataProfiles.get(0);
        return dataProfiles.get(0).getApnSetting();
    }

    /**
     * Get data profiles that can satisfy given network capabilities.
     * Generate a traffic-descriptor type data profile from a network request.
     *
     * @param networkCapabilities The network capabilities.
     * @return data profiles that can satisfy given network capabilities.
     * @param networkRequest The network request.
     * @return The generated data profile. {@code null} if not available.
     */
    @VisibleForTesting
    public @NonNull List<DataProfile> getDataProfilesForNetworkCapabilities(
            @NonNull @NetCapability int[] networkCapabilities) {
        return mAllDataProfiles.stream()
                .filter(dp -> dp.canSatisfy(networkCapabilities))
    private @Nullable DataProfile getTrafficDescriptorTypeDataProfile(
            @NonNull TelephonyNetworkRequest networkRequest) {
        if (!networkRequest.hasAttribute(
                TelephonyNetworkRequest.CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_OS_APP_ID)) {
            return null;
        }

        // If the network request also contains APN-type capabilities (for example, enterprise
        // is also an APN-type capability, then we fill in the corresponding APN setting in
        // data profile as well.
        ApnSetting apnSetting = null;
        if (networkRequest.hasAttribute(
                TelephonyNetworkRequest.CAPABILITY_ATTRIBUTE_APN_SETTING)) {
            // Put the preferred data profile at the top of the list, then the longest time
            // hasn't used data profile will be in the front so all the data profiles can be
            // tried.
                .sorted(Comparator.comparing((DataProfile dp) -> !dp.equals(mPreferredDataProfile))
            apnSetting = mAllDataProfiles.stream()
                    .filter(dataProfile -> dataProfile.getApnSetting() != null)
                    .filter(networkRequest::canBeSatisfiedBy)
                    .min(Comparator.comparing(
                            (DataProfile dp) -> !dp.equals(mPreferredDataProfile))
                            .thenComparingLong(DataProfile::getLastSetupTimestamp))
                .collect(Collectors.toList());
                    .map(DataProfile::getApnSetting)
                    .orElse(null);
        }

        byte[] osAppId = networkRequest.getOsAppId() != null
                ? networkRequest.getOsAppId().getBytes() : null;
        DataProfile dataProfile = new DataProfile.Builder()
                .setApnSetting(apnSetting)
                .setTrafficDescriptor(new TrafficDescriptor(
                        apnSetting != null ? apnSetting.getApnName() : null,
                        osAppId))
                .build();
        if (!mAllDataProfiles.contains(dataProfile)) {
            mAllDataProfiles.add(dataProfile);
        }
        return dataProfile;
    }

    /**
@@ -620,6 +729,14 @@ public class DataProfileManager extends Handler {
        Rlog.e(mLogTag, s);
    }

    /**
     * Log verbose messages.
     * @param s debug messages.
     */
    private void logv(@NonNull String s) {
        if (VDBG) Rlog.v(mLogTag, s);
    }

    /**
     * Log debug messages and also log into the local log.
     * @param s debug messages
Loading