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

Commit 61e6e280 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Migrated link bandwidth estimator to the new data stack"

parents e1164667 d91c9df9
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */

package com.android.internal.telephony;

import static com.android.internal.telephony.CommandException.Error.GENERIC_FAILURE;
import static com.android.internal.telephony.CommandException.Error.SIM_BUSY;
import static com.android.internal.telephony.CommandsInterface.CF_ACTION_DISABLE;
@@ -90,10 +91,10 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.cdma.CdmaMmiCode;
import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
import com.android.internal.telephony.data.DataNetworkController;
import com.android.internal.telephony.data.LinkBandwidthEstimator;
import com.android.internal.telephony.dataconnection.AccessNetworksManager;
import com.android.internal.telephony.dataconnection.DataEnabledSettings;
import com.android.internal.telephony.dataconnection.DcTracker;
import com.android.internal.telephony.dataconnection.LinkBandwidthEstimator;
import com.android.internal.telephony.dataconnection.TransportManager;
import com.android.internal.telephony.emergency.EmergencyNumberTracker;
import com.android.internal.telephony.gsm.GsmMmiCode;
+1 −1
Original line number Diff line number Diff line
@@ -77,11 +77,11 @@ import com.android.ims.ImsManager;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.data.DataNetworkController;
import com.android.internal.telephony.data.LinkBandwidthEstimator;
import com.android.internal.telephony.dataconnection.AccessNetworksManager;
import com.android.internal.telephony.dataconnection.DataConnectionReasons;
import com.android.internal.telephony.dataconnection.DataEnabledSettings;
import com.android.internal.telephony.dataconnection.DcTracker;
import com.android.internal.telephony.dataconnection.LinkBandwidthEstimator;
import com.android.internal.telephony.dataconnection.TransportManager;
import com.android.internal.telephony.emergency.EmergencyNumberTracker;
import com.android.internal.telephony.imsphone.ImsPhone;
+1 −1
Original line number Diff line number Diff line
@@ -34,10 +34,10 @@ import com.android.ims.ImsManager;
import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
import com.android.internal.telephony.cdma.EriManager;
import com.android.internal.telephony.data.DataNetworkController;
import com.android.internal.telephony.data.LinkBandwidthEstimator;
import com.android.internal.telephony.dataconnection.AccessNetworksManager;
import com.android.internal.telephony.dataconnection.DataEnabledSettings;
import com.android.internal.telephony.dataconnection.DcTracker;
import com.android.internal.telephony.dataconnection.LinkBandwidthEstimator;
import com.android.internal.telephony.dataconnection.TransportManager;
import com.android.internal.telephony.emergency.EmergencyNumberTracker;
import com.android.internal.telephony.imsphone.ImsExternalCallTracker;
+58 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.os.PersistableBundle;
import android.os.RegistrantList;
import android.telephony.Annotation.NetCapability;
import android.telephony.Annotation.NetworkType;
import android.telephony.Annotation.OverrideNetworkType;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -57,6 +58,28 @@ import java.util.concurrent.ConcurrentHashMap;
public class DataConfigManager extends Handler {
    private static final int EVENT_CARRIER_CONFIG_CHANGED = 1;

    /** Indicates the bandwidth estimation source is from the modem. */
    private static final String BANDWIDTH_SOURCE_MODEM_STRING_VALUE = "modem";

    /** Indicates the bandwidth estimation source is from the static carrier config. */
    private static final String BANDWIDTH_SOURCE_CARRIER_CONFIG_STRING_VALUE = "carrier_config";

    /** Indicates the bandwidth estimation source is from {@link LinkBandwidthEstimator}. */
    private static final String BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR_STRING_VALUE =
            "bandwidth_estimator";

    // /** Configuration used only network type GSM. Should not be used outside of DataConfigManager
    //   */
    // private static final String CONFIG_USED_NETWORK_TYPE_GPRS = "GPRS";

    // private static final String CONFIG_USED_NETWORK_TYPE_EDGE = "EDGE";

    // TODO: A lot more to be added.

    // private static final String CONFIG_USED_NETWORK_TYPE_NR_NSA = "NR_NSA";

    // private static final String CONFIG_USED_NETWORK_TYPE_NR_NSA_MMWAVE = "NR_NSA_MMWAVE";

    private final Phone mPhone;
    private final String mLogTag;

@@ -247,6 +270,39 @@ public class DataConfigManager extends Handler {
                .config_wlan_data_service_conn_persistence_on_restart);
    }

    /**
     * @return The bandwidth estimation source.
     */
    public @DataNetwork.BandwidthEstimationSource int getBandwidthEstimateSource() {
        String source = mResources.getString(
                com.android.internal.R.string.config_bandwidthEstimateSource);
        switch (source) {
            case BANDWIDTH_SOURCE_MODEM_STRING_VALUE:
                return DataNetwork.BANDWIDTH_SOURCE_MODEM;
            case BANDWIDTH_SOURCE_CARRIER_CONFIG_STRING_VALUE:
                return DataNetwork.BANDWIDTH_SOURCE_CARRIER_CONFIG;
            case BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR_STRING_VALUE:
                return DataNetwork.BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR;
            default:
                loge("Invalid bandwidth estimation source config: " + source);
                return DataNetwork.BANDWIDTH_SOURCE_UNKNOWN;
        }
    }

    /**
     * Get the bandwidth estimate from the carrier config.
     *
     * @param networkType The current network type.
     * @param overrideNetworkType The override network type. This is used to indicate 5G NSA and
     * millimeter wave case.
     * @return The pre-configured bandwidth estimate from carrier config.
     */
    public @NonNull DataNetwork.NetworkBandwidth getBandwidthForNetworkType(
            @NetworkType int networkType, @OverrideNetworkType int overrideNetworkType) {
        return new DataNetwork.NetworkBandwidth(0, 0);
        // TODO: Add the real implementation.
    }

    /**
     * Registration point for subscription info ready
     *
@@ -310,6 +366,8 @@ public class DataConfigManager extends Handler {
        pw.println("getImsDeregistrationDelay=" + getImsDeregistrationDelay());
        pw.println("shouldPersistIwlanDataNetworksWhenDataServiceRestarted="
                + shouldPersistIwlanDataNetworksWhenDataServiceRestarted());
        pw.println("Bandwidth estimation source=" + mResources.getString(
                com.android.internal.R.string.config_bandwidthEstimateSource));
        pw.decreaseIndent();
    }
}
+247 −8
Original line number Diff line number Diff line
@@ -45,9 +45,11 @@ import android.telephony.Annotation.DataState;
import android.telephony.Annotation.NetworkType;
import android.telephony.Annotation.ValidationStatus;
import android.telephony.DataFailCause;
import android.telephony.LinkCapacityEstimate;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.PreciseDataConnectionState;
import android.telephony.ServiceState;
import android.telephony.TelephonyDisplayInfo;
import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
import android.telephony.data.DataCallResponse;
@@ -58,6 +60,7 @@ import android.telephony.data.TrafficDescriptor;
import android.text.TextUtils;
import android.util.IndentingPrintWriter;
import android.util.LocalLog;
import android.util.Pair;
import android.util.SparseArray;
import android.util.SparseIntArray;

@@ -81,6 +84,7 @@ import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.function.Consumer;

@@ -146,6 +150,15 @@ public class DataNetwork extends StateMachine {
    /** Event for detaching all network requests. */
    private static final int EVENT_DETACH_ALL_NETWORK_REQUESTS = 10;

    /** Event for bandwidth estimation from the modem changed. */
    private static final int EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED = 11;

    /** Event for bandwidth estimation from the bandwidth estimator changed. */
    private static final int EVENT_BANDWIDTH_ESTIMATE_FROM_BANDWIDTH_ESTIMATOR_CHANGED = 12;

    /** Event for display info changed. This is for getting 5G NSA or mmwave information. */
    private static final int EVENT_DISPLAY_INFO_CHANGED = 13;

    /** The default MTU for IPv4 network */
    private static final int DEFAULT_MTU_V4 = 1280;

@@ -215,6 +228,67 @@ public class DataNetwork extends StateMachine {
    /** Data network tear down due to radio turned off by the carrier. */
    public static final int TEAR_DOWN_REASON_POWER_OFF_BY_CARRIER = 11;

    @IntDef(prefix = {"BANDWIDTH_SOURCE_"},
            value = {
                    BANDWIDTH_SOURCE_UNKNOWN,
                    BANDWIDTH_SOURCE_MODEM,
                    BANDWIDTH_SOURCE_CARRIER_CONFIG,
                    BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR,
            })
    public @interface BandwidthEstimationSource {}

    /** Indicates the bandwidth estimation source is unknown. This must be a configuration error. */
    public static final int BANDWIDTH_SOURCE_UNKNOWN = 0;

    /** Indicates the bandwidth estimation source is from the modem. */
    public static final int BANDWIDTH_SOURCE_MODEM = 1;

    /** Indicates the bandwidth estimation source is from the static carrier config. */
    public static final int BANDWIDTH_SOURCE_CARRIER_CONFIG = 2;

    /** Indicates the bandwidth estimation source is from {@link LinkBandwidthEstimator}. */
    public static final int BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR = 3;

    /** The parent state. Any messages not handled by the child state fallback to this. */
    private final DefaultState mDefaultState = new DefaultState();

    /**
     * The connecting state. This is the initial state of a data network.
     *
     * @see DataNetwork for the state machine diagram.
     */
    private final ConnectingState mConnectingState = new ConnectingState();

    /**
     * The connected state. This is the state when data network becomes usable.
     *
     * @see DataNetwork for the state machine diagram.
     */
    private final ConnectedState mConnectedState = new ConnectedState();

    /**
     * The handover state. This is the state when data network handover between IWLAN and cellular.
     *
     * @see DataNetwork for the state machine diagram.
     */
    private final HandoverState mHandoverState = new HandoverState();

    /**
     * The disconnecting state. This is the state when data network is about to be disconnected.
     * The network is still usable in this state, but the clients should be prepared to lose the
     * network in any moment.
     *
     * @see DataNetwork for the state machine diagram.
     */
    private final DisconnectingState mDisconnectingState = new DisconnectingState();

    /**
     * The disconnected state. This is the final state of a data network.
     *
     * @see DataNetwork for the state machine diagram.
     */
    private final DisconnectedState mDisconnectedState = new DisconnectedState();

    /** The phone instance. */
    private final @NonNull Phone mPhone;
    /**
@@ -236,13 +310,6 @@ public class DataNetwork extends StateMachine {
    /** Local log. */
    private final LocalLog mLocalLog = new LocalLog(128);

    private final DefaultState mDefaultState = new DefaultState();
    private final ConnectingState mConnectingState = new ConnectingState();
    private final ConnectedState mConnectedState = new ConnectedState();
    private final HandoverState mHandoverState = new HandoverState();
    private final DisconnectingState mDisconnectingState = new DisconnectingState();
    private final DisconnectedState mDisconnectedState = new DisconnectedState();

    /** The callback to receives data network state update. */
    private final @NonNull DataNetworkCallback mDataNetworkCallback;

@@ -287,6 +354,9 @@ public class DataNetwork extends StateMachine {
    /** The link properties of this data network. */
    private @NonNull LinkProperties mLinkProperties;

    /** The network bandwidth. */
    private @NonNull NetworkBandwidth mNetworkBandwidth = new NetworkBandwidth(14, 14);

    /** The network requests associated with this data network */
    private @NonNull NetworkRequestList mAttachedNetworkRequestList = new NetworkRequestList();

@@ -325,6 +395,28 @@ public class DataNetwork extends StateMachine {
     */
    private @TransportType int mPreferredTransport = AccessNetworkConstants.TRANSPORT_TYPE_INVALID;

    /**
     * The network bandwidth.
     */
    public static class NetworkBandwidth {
        /** The downlink bandwidth in Kbps. */
        public final int downlinkBandwidthKbps;

        /** The uplink Bandwidth in Kbps. */
        public final int uplinkBandwidthKbps;

        /**
         * Constructor.
         *
         * @param downlinkBandwidthKbps The downlink bandwidth in Kbps.
         * @param uplinkBandwidthKbps The uplink Bandwidth in Kbps.
         */
        public NetworkBandwidth(int downlinkBandwidthKbps, int uplinkBandwidthKbps) {
            this.downlinkBandwidthKbps = downlinkBandwidthKbps;
            this.uplinkBandwidthKbps = uplinkBandwidthKbps;
        }
    }

    /**
     * Data network callback. Should only be used by {@link DataNetworkController}.
     */
@@ -548,6 +640,8 @@ public class DataNetwork extends StateMachine {
                    onDataConfigUpdated();
                    break;
                case EVENT_SERVICE_STATE_CHANGED: {
                    // TODO: Should update suspend state when CSS indicator changes.
                    // TODO: Should update suspend state when call started/ended.
                    updateSuspendState();
                    // TODO: Update TCP buffer size
                    // TODO: Update Bandwidth
@@ -596,8 +690,10 @@ public class DataNetwork extends StateMachine {
                    onDataStateChanged(transport, (ArrayList<DataCallResponse>) ar.result);
                    break;
                }
                case EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED:
                case EVENT_BANDWIDTH_ESTIMATE_FROM_BANDWIDTH_ESTIMATOR_CHANGED:
                case EVENT_TEAR_DOWN_NETWORK:
                    // Ignore the request when not in the correct state.
                    // Ignore the events when not in the correct state.
                    break;
                default:
                    loge("Unhandled event " + eventToString(msg.what));
@@ -684,10 +780,39 @@ public class DataNetwork extends StateMachine {
            mDataNetworkCallback.invokeFromExecutor(
                    () -> mDataNetworkCallback.onConnected(DataNetwork.this));
            updateSuspendState();

            mPhone.getDisplayInfoController().registerForTelephonyDisplayInfoChanged(
                    getHandler(), EVENT_DISPLAY_INFO_CHANGED, null);
            // TODO: Register for the following events after handover from IWLAN to cellular.
            if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
                int bandwidthEstimateSource = mDataConfigManager.getBandwidthEstimateSource();
                if (bandwidthEstimateSource == BANDWIDTH_SOURCE_MODEM) {
                    mPhone.mCi.registerForLceInfo(getHandler(),
                            EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED, null);
                } else if (bandwidthEstimateSource == BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR) {
                    mPhone.getLinkBandwidthEstimator().registerForBandwidthChanged(getHandler(),
                            EVENT_BANDWIDTH_ESTIMATE_FROM_BANDWIDTH_ESTIMATOR_CHANGED, null);
                } else {
                    loge("Invalid bandwidth source configuration: " + bandwidthEstimateSource);
                }
            }
        }

        @Override
        public void exit() {
            // TODO: Unregister for the following events after handover from cellular to IWLAN.
            if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
                int bandwidthEstimateSource = mDataConfigManager.getBandwidthEstimateSource();
                if (bandwidthEstimateSource == BANDWIDTH_SOURCE_MODEM) {
                    mPhone.mCi.unregisterForLceInfo(getHandler());
                } else if (bandwidthEstimateSource == BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR) {
                    mPhone.getLinkBandwidthEstimator().unregisterForBandwidthChanged(getHandler());
                } else {
                    loge("Invalid bandwidth source configuration: " + bandwidthEstimateSource);
                }
            }
            mPhone.getDisplayInfoController().unregisterForTelephonyDisplayInfoChanged(
                    getHandler());
        }

        @Override
@@ -704,6 +829,23 @@ public class DataNetwork extends StateMachine {
                    transitionTo(mDisconnectingState);
                    onTearDown(msg.arg1);
                    break;
                case EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED:
                    AsyncResult ar = (AsyncResult) msg.obj;
                    if (ar.exception != null) {
                        log("EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED: error ignoring, e="
                                + ar.exception);
                        break;
                    }
                    onBandwidthUpdatedFromModem((List<LinkCapacityEstimate>) ar.result);
                    break;
                case EVENT_BANDWIDTH_ESTIMATE_FROM_BANDWIDTH_ESTIMATOR_CHANGED:
                    ar = (AsyncResult) msg.obj;
                    Pair<Integer, Integer> pair = (Pair<Integer, Integer>) ar.result;
                    onBandwidthUpdated(pair.first, pair.second);
                    break;
                case EVENT_DISPLAY_INFO_CHANGED:
                    onDisplayInfoChanged();
                    break;
                default:
                    return NOT_HANDLED;
            }
@@ -743,6 +885,8 @@ public class DataNetwork extends StateMachine {

    /**
     * The disconnecting state. This is the state when data network is about to be disconnected.
     * The network is still usable in this state, but the clients should be prepared to lose the
     * network in any moment.
     *
     * @see DataNetwork for the state machine diagram.
     */
@@ -881,6 +1025,10 @@ public class DataNetwork extends StateMachine {
            builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
        }

        // Set the bandwidth information.
        builder.setLinkDownstreamBandwidthKbps(mNetworkBandwidth.downlinkBandwidthKbps);
        builder.setLinkUpstreamBandwidthKbps(mNetworkBandwidth.uplinkBandwidthKbps);

        NetworkCapabilities nc = builder.build();
        if (!nc.equals(mNetworkCapabilities)) {
            mNetworkCapabilities = nc;
@@ -1377,6 +1525,97 @@ public class DataNetwork extends StateMachine {
     */
    private void onDataConfigUpdated() {
        log("onDataConfigUpdated");

        updateBandwidthFromDataConfig();
    }

    /**
     * Called when receiving bandwidth update from the modem.
     *
     * @param linkCapacityEstimates The link capacity estimate list from the modem.
     */
    private void onBandwidthUpdatedFromModem(
            @NonNull List<LinkCapacityEstimate> linkCapacityEstimates) {
        Objects.requireNonNull(linkCapacityEstimates);
        if (linkCapacityEstimates.isEmpty()) return;

        int uplinkBandwidthKbps = 0, downlinkBandwidthKbps = 0;
        for (LinkCapacityEstimate linkCapacityEstimate : linkCapacityEstimates) {
            if (linkCapacityEstimate.getType() == LinkCapacityEstimate.LCE_TYPE_COMBINED) {
                uplinkBandwidthKbps = linkCapacityEstimate.getUplinkCapacityKbps();
                downlinkBandwidthKbps = linkCapacityEstimate.getDownlinkCapacityKbps();
                break;
            } else if (linkCapacityEstimate.getType() == LinkCapacityEstimate.LCE_TYPE_PRIMARY
                    || linkCapacityEstimate.getType() == LinkCapacityEstimate.LCE_TYPE_SECONDARY) {
                uplinkBandwidthKbps += linkCapacityEstimate.getUplinkCapacityKbps();
                downlinkBandwidthKbps += linkCapacityEstimate.getDownlinkCapacityKbps();
            } else {
                loge("Invalid LinkCapacityEstimate type " + linkCapacityEstimate.getType());
            }
        }
        onBandwidthUpdated(uplinkBandwidthKbps, downlinkBandwidthKbps);
    }

    /**
     * Called when bandwidth estimation updated from either modem or the bandwidth estimator.
     *
     * @param uplinkBandwidthKbps Uplink bandwidth estimate in Kbps.
     * @param downlinkBandwidthKbps Downlink bandwidth estimate in Kbps.
     */
    private void onBandwidthUpdated(int uplinkBandwidthKbps, int downlinkBandwidthKbps) {
        log("onBandwidthUpdated: downlinkBandwidthKbps=" + downlinkBandwidthKbps
                + ", uplinkBandwidthKbps=" + uplinkBandwidthKbps);
        TelephonyDisplayInfo displayInfo = mPhone.getDisplayInfoController()
                .getTelephonyDisplayInfo();
        NetworkBandwidth bandwidthFromConfig = null;
        if (displayInfo != null) {
            bandwidthFromConfig = mDataConfigManager.getBandwidthForNetworkType(
                    getDataNetworkType(), displayInfo.getOverrideNetworkType());
        }

        if (downlinkBandwidthKbps == LinkCapacityEstimate.INVALID && bandwidthFromConfig != null) {
            // Fallback to carrier config.
            downlinkBandwidthKbps = bandwidthFromConfig.downlinkBandwidthKbps;
        }

        if (uplinkBandwidthKbps == LinkCapacityEstimate.INVALID && bandwidthFromConfig != null) {
            // Fallback to carrier config.
            uplinkBandwidthKbps = bandwidthFromConfig.uplinkBandwidthKbps;
        }

        // Make sure uplink is not greater than downlink.
        uplinkBandwidthKbps = Math.min(uplinkBandwidthKbps, downlinkBandwidthKbps);
        mNetworkBandwidth = new NetworkBandwidth(downlinkBandwidthKbps, uplinkBandwidthKbps);

        updateNetworkCapabilities();
    }

    /**
     * Called when display info changed. This can happen when network types changed or override
     * types (5G NSA, 5G MMWAVE) changes.
     */
    private void onDisplayInfoChanged() {
        updateBandwidthFromDataConfig();

        // TODO: Update meteredness flags.
    }

    /**
     * Update the bandwidth from carrier config. Note this is no-op if the bandwidth source is not
     * carrier config.
     */
    private void updateBandwidthFromDataConfig() {
        if (mDataConfigManager.getBandwidthEstimateSource() != BANDWIDTH_SOURCE_CARRIER_CONFIG) {
            return;
        }
        log("updateBandwidthFromDataConfig");
        TelephonyDisplayInfo displayInfo = mPhone.getDisplayInfoController()
                .getTelephonyDisplayInfo();
        if (displayInfo != null) {
            mNetworkBandwidth = mDataConfigManager.getBandwidthForNetworkType(
                    getDataNetworkType(), displayInfo.getOverrideNetworkType());
            updateNetworkCapabilities();
        }
    }

    /**
Loading