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

Commit 660fc18a authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes from topics "td_based_caps", "urllc_embb"

* changes:
  Create general toString method for AIDL-generated Java classes
  Supported URLLC, EMBB, and CBS slicing
  Supported traffic descriptor based network capability
parents db563504 7957bd38
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -5661,7 +5661,22 @@ public class RIL extends BaseCommands implements CommandsInterface {
            }
            s = sb.toString();
        } else {
            // Check if toString() was overridden. Java classes created from HIDL have a built-in
            // toString() method, but AIDL classes only have it if the parcelable contains a
            // @JavaDerive annotation. Manually convert to String as a backup for AIDL parcelables
            // missing the annotation.
            boolean toStringExists = false;
            try {
                toStringExists = ret.getClass().getMethod("toString").getDeclaringClass()
                        != Object.class;
            } catch (NoSuchMethodException e) {
                Rlog.e(RILJ_LOG_TAG, e.getMessage());
            }
            if (toStringExists) {
                s = ret.toString();
            } else {
                s = RILUtils.convertToString(ret) + " [convertToString]";
            }
        }
        return s;
    }
+144 −14
Original line number Diff line number Diff line
@@ -349,6 +349,10 @@ import com.android.telephony.Rlog;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.util.ArrayList;
@@ -356,6 +360,8 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

@@ -378,6 +384,10 @@ public class RILUtils {
    public static final String RADIO_POWER_FAILURE_NO_RF_CALIBRATION_UUID =
            "316f3801-fa21-4954-a42f-0041eada3b33";

    private static final Set<Class> WRAPPER_CLASSES = new HashSet(Arrays.asList(
            Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class,
            Float.class, Double.class));

    /**
     * Convert to PersoSubstate defined in radio/1.5/types.hal
     * @param persoType PersoSubState type
@@ -1003,10 +1013,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();
    }
@@ -3483,8 +3502,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;
@@ -3617,7 +3641,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()
@@ -3667,33 +3695,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();
    }
@@ -3706,7 +3735,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(),
@@ -3729,7 +3768,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
@@ -4469,7 +4512,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(
@@ -5116,6 +5159,93 @@ public class RILUtils {
        return caps;
    }

    private static boolean isPrimitiveOrWrapper(Class c) {
        return c.isPrimitive() || WRAPPER_CLASSES.contains(c);
    }

    /**
     * Return a general String representation of a class
     * @param o The object to convert to String
     * @return A string containing all public non-static local variables of a class
     */
    public static String convertToString(Object o) {
        if (isPrimitiveOrWrapper(o.getClass()) || o.getClass() == String.class) return o.toString();
        if (o.getClass().isArray()) {
            // Special handling for arrays
            StringBuilder sb = new StringBuilder("[");
            boolean added = false;
            for (Object element : (Object[]) o) {
                sb.append(convertToString(element)).append(", ");
                added = true;
            }
            if (added) {
                // Remove extra ,
                sb.delete(sb.length() - 2, sb.length());
            }
            sb.append("]");
            return sb.toString();
        }
        StringBuilder sb = new StringBuilder(o.getClass().getSimpleName());
        sb.append("{");
        Field[] fields = o.getClass().getDeclaredFields();
        int tag = -1;
        try {
            tag = (int) o.getClass().getDeclaredMethod("getTag").invoke(o);
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            loge(e.getMessage());
        }
        if (tag != -1) {
            // Special handling for unions
            String tagName = null;
            try {
                Method method = o.getClass().getDeclaredMethod("_tagString", int.class);
                method.setAccessible(true);
                tagName = (String) method.invoke(o, tag);
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                loge(e.getMessage());
            }
            if (tagName != null) {
                sb.append(tagName);
                sb.append("=");
                // From tag, create method name getTag
                String getTagMethod = "get" + tagName.substring(0, 1).toUpperCase(Locale.ROOT)
                        + tagName.substring(1);
                Object val = null;
                try {
                    val = o.getClass().getDeclaredMethod(getTagMethod).invoke(o);
                } catch (NoSuchMethodException | IllegalAccessException
                        | InvocationTargetException e) {
                    loge(e.getMessage());
                }
                if (val != null) {
                    sb.append(convertToString(val));
                }
            }
        } else {
            boolean added = false;
            for (Field field : fields) {
                // Ignore static variables
                if (Modifier.isStatic(field.getModifiers())) continue;
                sb.append(field.getName()).append("=");
                Object val = null;
                try {
                    val = field.get(o);
                } catch (IllegalAccessException e) {
                    loge(e.getMessage());
                }
                if (val == null) continue;
                sb.append(convertToString(val)).append(", ");
                added = true;
            }
            if (added) {
                // Remove extra ,
                sb.delete(sb.length() - 2, sb.length());
            }
        }
        sb.append("}");
        return sb.toString();
    }

    private static void logd(String log) {
        Rlog.d("RILUtils", log);
    }
+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
@@ -1780,7 +1780,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()));
    }

@@ -2525,13 +2525,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.
Loading