/*
 * Copyright 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.telephony.data;

import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.NetworkAgent;
import android.net.NetworkAgentConfig;
import android.net.NetworkCapabilities;
import android.net.NetworkFactory;
import android.net.NetworkProvider;
import android.net.NetworkScore;
import android.net.ProxyInfo;
import android.net.RouteInfo;
import android.net.TelephonyNetworkSpecifier;
import android.net.Uri;
import android.net.vcn.VcnManager;
import android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener;
import android.net.vcn.VcnNetworkPolicyResult;
import android.os.AsyncResult;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.os.SystemClock;
import android.provider.Telephony;
import android.telephony.AccessNetworkConstants;
import android.telephony.AccessNetworkConstants.AccessNetworkType;
import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.Annotation.DataFailureCause;
import android.telephony.Annotation.DataState;
import android.telephony.Annotation.NetCapability;
import android.telephony.Annotation.NetworkType;
import android.telephony.Annotation.ValidationStatus;
import android.telephony.AnomalyReporter;
import android.telephony.DataFailCause;
import android.telephony.DataSpecificRegistrationInfo;
import android.telephony.LinkCapacityEstimate;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.PcoData;
import android.telephony.PreciseDataConnectionState;
import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionPlan;
import android.telephony.TelephonyDisplayInfo;
import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
import android.telephony.data.DataCallResponse;
import android.telephony.data.DataCallResponse.HandoverFailureMode;
import android.telephony.data.DataCallResponse.LinkStatus;
import android.telephony.data.DataProfile;
import android.telephony.data.DataService;
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;
import android.util.LocalLog;
import android.util.SparseArray;
import android.util.SparseIntArray;

import com.android.internal.telephony.CarrierSignalAgent;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.RIL;
import com.android.internal.telephony.data.DataEvaluation.DataAllowedReason;
import com.android.internal.telephony.data.DataNetworkController.NetworkRequestList;
import com.android.internal.telephony.data.DataRetryManager.DataHandoverRetryEntry;
import com.android.internal.telephony.data.DataRetryManager.DataRetryEntry;
import com.android.internal.telephony.data.LinkBandwidthEstimator.LinkBandwidthEstimatorCallback;
import com.android.internal.telephony.data.TelephonyNetworkAgent.TelephonyNetworkAgentCallback;
import com.android.internal.telephony.metrics.DataCallSessionStats;
import com.android.internal.telephony.metrics.TelephonyMetrics;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.IState;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import com.android.net.module.util.LinkPropertiesUtils;
import com.android.net.module.util.NetUtils;
import com.android.net.module.util.NetworkCapabilitiesUtils;
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;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * DataNetwork class represents a single PDN (Packet Data Network).
 *
 * The life cycle of a data network starts from {@link ConnectingState}. If setup data request
 * succeeds, then it enters {@link ConnectedState}, otherwise it enters
 * {@link DisconnectedState}.
 *
 * When data network is in {@link ConnectingState}, it can enter {@link HandoverState} if handover
 * between IWLAN and cellular occurs. After handover completes or fails, it return back to
 * {@link ConnectedState}. When the data network is about to be disconnected, it first enters
 * {@link DisconnectingState} when performing graceful tear down or when sending the data
 * deactivation request. At the end, it enters {@link DisconnectedState} when {@link DataService}
 * notifies data disconnected. Note that an unsolicited disconnected event from {@link DataService}
 * or any vendor HAL failure response can immediately move data network from {@link ConnectedState}
 * to {@link DisconnectedState}. {@link DisconnectedState} is the final state of a data network.
 *
 * State machine diagram:
 *
 *
 *                                  ┌─────────┐
 *                                  │Handover │
 *                                  └─▲────┬──┘
 *                                    │    │
 *             ┌───────────┐        ┌─┴────▼──┐        ┌──────────────┐
 *             │Connecting ├────────►Connected├────────►Disconnecting │
 *             └─────┬─────┘        └────┬────┘        └───────┬──────┘
 *                   │                   │                     │
 *                   │             ┌─────▼──────┐              │
 *                   └─────────────►Disconnected◄──────────────┘
 *                                 └────────────┘
 *
 */
public class DataNetwork extends StateMachine {
    private static final boolean VDBG = false;
    /** Event for data config updated. */
    private static final int EVENT_DATA_CONFIG_UPDATED = 1;

    /** Event for attaching a network request. */
    private static final int EVENT_ATTACH_NETWORK_REQUEST = 2;

    /** Event for detaching a network request. */
    private static final int EVENT_DETACH_NETWORK_REQUEST = 3;

    /** Event for allocating PDU session id response. */
    private static final int EVENT_ALLOCATE_PDU_SESSION_ID_RESPONSE = 5;

    /** Event for setup data network response. */
    private static final int EVENT_SETUP_DATA_NETWORK_RESPONSE = 6;

    /** Event for tearing down data network. */
    private static final int EVENT_TEAR_DOWN_NETWORK = 7;

    /** Event triggered by {@link DataServiceCallback#onDataCallListChanged(List)}. */
    private static final int EVENT_DATA_STATE_CHANGED = 8;

    /** Data network service state changed event. */
    private static final int EVENT_SERVICE_STATE_CHANGED = 9;

    /** 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 display info changed. This is for getting 5G NSA or mmwave information. */
    private static final int EVENT_DISPLAY_INFO_CHANGED = 13;

    /** Event for initiating an handover between cellular and IWLAN. */
    private static final int EVENT_START_HANDOVER = 14;

    /** Event for setup data call (for handover) response from the data service. */
    private static final int EVENT_HANDOVER_RESPONSE = 15;

    /** Event for subscription plan changed or unmetered/congested override set. */
    private static final int EVENT_SUBSCRIPTION_PLAN_OVERRIDE = 16;

    /** Event for PCO data received from network. */
    private static final int EVENT_PCO_DATA_RECEIVED = 17;

    /** Event for carrier privileged UIDs changed. */
    private static final int EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED = 18;

    /** Event for deactivate data network response. */
    private static final int EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE = 19;

    /**
     * Event for data network stuck in transient (i.e. connecting/disconnecting/handover) state for
     * too long time. Timeout value specified in
     * {@link DataConfigManager#getAnomalyNetworkConnectingTimeoutMs()},
     * {@link DataConfigManager#getAnomalyNetworkDisconnectingTimeoutMs()},
     * {@link DataConfigManager#getNetworkHandoverTimeoutMs()}.
     */
    private static final int EVENT_STUCK_IN_TRANSIENT_STATE = 20;

    /**
     * Event for waiting for tearing down condition met. This will cause data network entering
     * disconnecting state.
     */
    private static final int EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET = 21;

    /** Event for call started. */
    private static final int EVENT_VOICE_CALL_STARTED = 22;

    /** Event for call ended. */
    private static final int EVENT_VOICE_CALL_ENDED = 23;

    /** Event for CSS indicator changed. */
    private static final int EVENT_CSS_INDICATOR_CHANGED = 24;

    /** Invalid context id. */
    private static final int INVALID_CID = -1;

    /**
     * The data network providing default internet will have a higher score of 50. Other network
     * will have a slightly lower score of 45. The intention is other connections will not cause
     * connectivity service to tear down default internet connection. For example, to validate
     * internet connection on non-default data SIM, we'll set up a temporary internet network on
     * that data SIM. In this case, score of 45 is assigned so connectivity service will not replace
     * the default internet network with it.
     */
    private static final int DEFAULT_INTERNET_NETWORK_SCORE = 50;
    private static final int OTHER_NETWORK_SCORE = 45;

    @IntDef(prefix = {"DEACTIVATION_REASON_"},
            value = {
                    TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED,
                    TEAR_DOWN_REASON_SIM_REMOVAL,
                    TEAR_DOWN_REASON_AIRPLANE_MODE_ON,
                    TEAR_DOWN_REASON_DATA_DISABLED,
                    TEAR_DOWN_REASON_NO_LIVE_REQUEST,
                    TEAR_DOWN_REASON_RAT_NOT_ALLOWED,
                    TEAR_DOWN_REASON_ROAMING_DISABLED,
                    TEAR_DOWN_REASON_CONCURRENT_VOICE_DATA_NOT_ALLOWED,
                    TEAR_DOWN_REASON_DATA_SERVICE_NOT_READY,
                    TEAR_DOWN_REASON_POWER_OFF_BY_CARRIER,
                    TEAR_DOWN_REASON_DATA_STALL,
                    TEAR_DOWN_REASON_HANDOVER_FAILED,
                    TEAR_DOWN_REASON_HANDOVER_NOT_ALLOWED,
                    TEAR_DOWN_REASON_VCN_REQUESTED,
                    TEAR_DOWN_REASON_VOPS_NOT_SUPPORTED,
                    TEAR_DOWN_REASON_DEFAULT_DATA_UNSELECTED,
                    TEAR_DOWN_REASON_NOT_IN_SERVICE,
                    TEAR_DOWN_REASON_DATA_CONFIG_NOT_READY,
                    TEAR_DOWN_REASON_PENDING_TEAR_DOWN_ALL,
                    TEAR_DOWN_REASON_NO_SUITABLE_DATA_PROFILE,
                    TEAR_DOWN_REASON_CDMA_EMERGENCY_CALLBACK_MODE,
                    TEAR_DOWN_REASON_RETRY_SCHEDULED,
                    TEAR_DOWN_REASON_DATA_THROTTLED,
                    TEAR_DOWN_REASON_DATA_PROFILE_INVALID,
                    TEAR_DOWN_REASON_DATA_PROFILE_NOT_PREFERRED,
                    TEAR_DOWN_REASON_NOT_ALLOWED_BY_POLICY,
                    TEAR_DOWN_REASON_ILLEGAL_STATE,
                    TEAR_DOWN_REASON_ONLY_ALLOWED_SINGLE_NETWORK,
                    TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED,
            })
    public @interface TearDownReason {}

    /** Data network tear down requested by connectivity service. */
    public static final int TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED = 1;

    /** Data network tear down due to SIM removal. */
    public static final int TEAR_DOWN_REASON_SIM_REMOVAL = 2;

    /** Data network tear down due to airplane mode turned on. */
    public static final int TEAR_DOWN_REASON_AIRPLANE_MODE_ON = 3;

    /** Data network tear down due to data disabled (by user, policy, carrier, etc...). */
    public static final int TEAR_DOWN_REASON_DATA_DISABLED = 4;

    /** Data network tear down due to no live network request. */
    public static final int TEAR_DOWN_REASON_NO_LIVE_REQUEST = 5;

    /** Data network tear down due to current RAT is not allowed by the data profile. */
    public static final int TEAR_DOWN_REASON_RAT_NOT_ALLOWED = 6;

    /** Data network tear down due to data roaming not enabled. */
    public static final int TEAR_DOWN_REASON_ROAMING_DISABLED = 7;

    /** Data network tear down due to concurrent voice/data not allowed. */
    public static final int TEAR_DOWN_REASON_CONCURRENT_VOICE_DATA_NOT_ALLOWED = 8;



    /** Data network tear down due to data service unbound. */
    public static final int TEAR_DOWN_REASON_DATA_SERVICE_NOT_READY = 10;

    /** Data network tear down due to radio turned off by the carrier. */
    public static final int TEAR_DOWN_REASON_POWER_OFF_BY_CARRIER = 11;

    /** Data network tear down due to data stall. */
    public static final int TEAR_DOWN_REASON_DATA_STALL = 12;

    /** Data network tear down due to handover failed. */
    public static final int TEAR_DOWN_REASON_HANDOVER_FAILED = 13;

    /** Data network tear down due to handover not allowed. */
    public static final int TEAR_DOWN_REASON_HANDOVER_NOT_ALLOWED = 14;

    /** Data network tear down due to VCN service requested. */
    public static final int TEAR_DOWN_REASON_VCN_REQUESTED = 15;

    /** Data network tear down due to VOPS no longer supported. */
    public static final int TEAR_DOWN_REASON_VOPS_NOT_SUPPORTED = 16;

    /** Data network tear down due to default data unselected. */
    public static final int TEAR_DOWN_REASON_DEFAULT_DATA_UNSELECTED = 17;

    /** Data network tear down due to device not in service. */
    public static final int TEAR_DOWN_REASON_NOT_IN_SERVICE = 18;

    /** Data network tear down due to data config not ready. */
    public static final int TEAR_DOWN_REASON_DATA_CONFIG_NOT_READY = 19;

    /** Data network tear down due to tear down all pending. */
    public static final int TEAR_DOWN_REASON_PENDING_TEAR_DOWN_ALL = 20;

    /** Data network tear down due to no suitable data profile. */
    public static final int TEAR_DOWN_REASON_NO_SUITABLE_DATA_PROFILE = 21;

    /** Data network tear down due to CDMA ECBM. */
    public static final int TEAR_DOWN_REASON_CDMA_EMERGENCY_CALLBACK_MODE = 22;

    /** Data network tear down due to retry scheduled. */
    public static final int TEAR_DOWN_REASON_RETRY_SCHEDULED = 23;

    /** Data network tear down due to data throttled. */
    public static final int TEAR_DOWN_REASON_DATA_THROTTLED = 24;

    /** Data network tear down due to data profile invalid. */
    public static final int TEAR_DOWN_REASON_DATA_PROFILE_INVALID = 25;

    /** Data network tear down due to data profile not preferred. */
    public static final int TEAR_DOWN_REASON_DATA_PROFILE_NOT_PREFERRED = 26;

    /** Data network tear down due to not allowed by policy. */
    public static final int TEAR_DOWN_REASON_NOT_ALLOWED_BY_POLICY = 27;

    /** Data network tear down due to illegal state. */
    public static final int TEAR_DOWN_REASON_ILLEGAL_STATE = 28;

    /** Data network tear down due to only allowed single network. */
    public static final int TEAR_DOWN_REASON_ONLY_ALLOWED_SINGLE_NETWORK = 29;

    /** Data network tear down due to preferred data switched to another phone. */
    public static final int TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED = 30;

    @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 capabilities that are allowed to changed dynamically during the life cycle of network.
     * This is copied from {@code NetworkCapabilities#MUTABLE_CAPABILITIES}. There is no plan to
     * make this a connectivity manager API since in the future, immutable network capabilities
     * would be allowed to changed dynamically. (i.e. not immutable anymore.)
     */
    private static final List<Integer> MUTABLE_CAPABILITIES = List.of(
            NetworkCapabilities.NET_CAPABILITY_TRUSTED,
            NetworkCapabilities.NET_CAPABILITY_VALIDATED,
            NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL,
            NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING,
            NetworkCapabilities.NET_CAPABILITY_FOREGROUND,
            NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED,
            NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED,
            NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY,
            NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED,
            NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED,
            NetworkCapabilities.NET_CAPABILITY_HEAD_UNIT,
            // Connectivity service will support NOT_METERED as a mutable and requestable
            // capability.
            NetworkCapabilities.NET_CAPABILITY_NOT_METERED,
            // Even though MMTEL is an immutable capability, we still make it an mutable capability
            // here before we have a better solution to deal with network transition from VoPS
            // to non-VoPS network.
            NetworkCapabilities.NET_CAPABILITY_MMTEL
    );

    /** 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. This state is particular useful for IMS graceful tear down, where
     * the network enters disconnecting state while waiting for IMS de-registration signal.
     *
     * @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;

    /**
     * The subscription id. This is assigned when the network is created, and not supposed to
     * change afterwards.
     */
    private final int mSubId;

    /** The network score of this network. */
    private int mNetworkScore;

    /**
     * Indicates that
     * {@link DataService.DataServiceProvider#deactivateDataCall(int, int, DataServiceCallback)}
     * has been called. This flag can be only changed from {@code false} to {@code true}.
     */
    private boolean mInvokedDataDeactivation = false;

    /**
     * Indicates that if the data network has ever entered {@link ConnectedState}.
     */
    private boolean mEverConnected = false;

    /** RIL interface. */
    private final @NonNull CommandsInterface mRil;

    /** Local log. */
    private final LocalLog mLocalLog = new LocalLog(128);

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

    /** The log tag. */
    private String mLogTag;

    /** Metrics of per data network connection. */
    private final DataCallSessionStats mDataCallSessionStats;

    /**
     * The unique context id assigned by the data service in {@link DataCallResponse#getId()}. One
     * for {@link AccessNetworkConstants#TRANSPORT_TYPE_WWAN} and one for
     * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}. The reason for storing both is that
     * during handover, both cid will be used.
     */
    private final SparseIntArray mCid = new SparseIntArray(2);

    /**
     * The initial network agent id. The network agent can be re-created due to immutable capability
     * changed. This is to preserve the initial network agent id so the id in the logging tag won't
     * change for the entire life cycle of data network.
     */
    private int mInitialNetworkAgentId;

    /** PDU session id. */
    private int mPduSessionId = DataCallResponse.PDU_SESSION_ID_NOT_SET;

    /**
     * Data service managers for accessing {@link AccessNetworkConstants#TRANSPORT_TYPE_WWAN} and
     * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN} data services.
     */
    private final @NonNull SparseArray<DataServiceManager> mDataServiceManagers;

    /** Access networks manager. */
    private final @NonNull AccessNetworksManager mAccessNetworksManager;

    /** Data network controller. */
    private final @NonNull DataNetworkController mDataNetworkController;

    /** Data config manager. */
    private final @NonNull DataConfigManager mDataConfigManager;

    /** VCN manager. */
    private final @Nullable VcnManager mVcnManager;

    /** VCN policy changed listener. */
    private @Nullable VcnNetworkPolicyChangeListener mVcnPolicyChangeListener;

    /** The network agent associated with this data network. */
    private @NonNull TelephonyNetworkAgent mNetworkAgent;

    /** QOS callback tracker. This is only created after network connected on WWAN. */
    private @Nullable QosCallbackTracker mQosCallbackTracker;

    /** NAT keepalive tracker. */
    private @Nullable KeepaliveTracker mKeepaliveTracker;

    /** The data profile used to establish this data network. */
    private @NonNull DataProfile mDataProfile;

    /**
     * The data profile used for data handover. Some carriers might use different data profile
     * between IWLAN and cellular. Only set before handover started.
     */
    private @Nullable DataProfile mHandoverDataProfile;

    /** 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;

    /** The network slice info. */
    private @Nullable NetworkSliceInfo mNetworkSliceInfo;

    /** The link status (i.e. RRC state). */
    private @LinkStatus int mLinkStatus = DataCallResponse.LINK_STATUS_UNKNOWN;

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

    /** The TCP buffer sizes config. */
    private @NonNull String mTcpBufferSizes;

    /** The telephony display info. */
    private @NonNull TelephonyDisplayInfo mTelephonyDisplayInfo;

    /** Whether {@link NetworkCapabilities#NET_CAPABILITY_TEMPORARILY_NOT_METERED} is supported. */
    private boolean mTempNotMeteredSupported = false;

    /** Whether the current data network is temporarily not metered. */
    private boolean mTempNotMetered = false;

    /** Whether the current data network is congested. */
    private boolean mCongested = false;

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

    /**
     * The latest data call response received from either
     * {@link DataServiceCallback#onSetupDataCallComplete(int, DataCallResponse)} or
     * {@link DataServiceCallback#onDataCallListChanged(List)}. The very first update must be
     * from {@link DataServiceCallback#onSetupDataCallComplete(int, DataCallResponse)}.
     */
    private @Nullable DataCallResponse mDataCallResponse = null;

    /**
     * The fail cause from either setup data failure or unsolicited disconnect reported by data
     * service.
     */
    private @DataFailureCause int mFailCause = DataFailCause.NONE;

    /**
     * The retry delay in milliseconds from setup data failure.
     */
    private long mRetryDelayMillis = DataCallResponse.RETRY_DURATION_UNDEFINED;

    /**
     * Indicates if data network is suspended. Note this is slightly different from the
     * {@link TelephonyManager#DATA_SUSPENDED}, which is only possible when data network is in
     * connected state. This flag reflects to the
     * {@link NetworkCapabilities#NET_CAPABILITY_NOT_SUSPENDED} which can happen when data network
     * is in connected or disconnecting state.
     */
    private boolean mSuspended = false;

    /**
     * The current transport of the data network. For handover, the current transport will be set
     * after handover completes.
     */
    private @TransportType int mTransport;

    /** The reason that why setting up this data network is allowed. */
    private @NonNull DataAllowedReason mDataAllowedReason;

    /**
     * PCO (Protocol Configuration Options) data received from the network. The first key is the
     * cid of the PCO data, the second key is the PCO id, the value is the PCO data.
     */
    private final @NonNull Map<Integer, Map<Integer, PcoData>> mPcoData = new ArrayMap<>();

    /** The QOS bearer sessions. */
    private final @NonNull List<QosBearerSession> mQosBearerSessions = new ArrayList<>();

    /**
     * The UIDs of packages that have carrier privilege.
     */
    private @NonNull int[] mAdministratorUids = new int[0];

    /**
     * Carrier service package uid. This UID will not change through the life cycle of data network.
     */
    private int mCarrierServicePackageUid = Process.INVALID_UID;

    /**
     * Link bandwidth estimator callback for receiving latest link bandwidth information.
     */
    private @Nullable LinkBandwidthEstimatorCallback mLinkBandwidthEstimatorCallback;

    /**
     * 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;
        }

        @Override
        public String toString() {
            return String.format("NetworkBandwidth=[downlink=%d, uplink=%d]",
                    downlinkBandwidthKbps, uplinkBandwidthKbps);
        }
    }

    /**
     * Data network callback. Should only be used by {@link DataNetworkController}.
     */
    public abstract static class DataNetworkCallback extends DataCallback {
        /**
         * Constructor
         *
         * @param executor The executor of the callback.
         */
        public DataNetworkCallback(@NonNull @CallbackExecutor Executor executor) {
            super(executor);
        }

        /**
         * Called when data setup failed.
         *
         * @param dataNetwork The data network.
         * @param requestList The network requests attached to this data network.
         * @param cause The fail cause of setup data network.
         * @param retryDurationMillis The network suggested data retry duration in milliseconds as
         * specified in 3GPP TS 24.302 section 8.2.9.1. The {@link DataProfile} associated to this
         * data network will be throttled for the specified duration unless
         * {@link DataServiceCallback#onApnUnthrottled} is called. {@link Long#MAX_VALUE} indicates
         * data retry should not occur. {@link DataCallResponse#RETRY_DURATION_UNDEFINED} indicates
         * network did not suggest any retry duration.
         */
        public abstract void onSetupDataFailed(@NonNull DataNetwork dataNetwork,
                @NonNull NetworkRequestList requestList, @DataFailureCause int cause,
                long retryDurationMillis);

        /**
         * Called when data network enters {@link ConnectedState}.
         *
         * @param dataNetwork The data network.
         */
        public abstract void onConnected(@NonNull DataNetwork dataNetwork);

        /**
         * Called when data network validation status changed.
         *
         * @param dataNetwork The data network.
         * @param status one of {@link NetworkAgent#VALIDATION_STATUS_VALID} or
         * {@link NetworkAgent#VALIDATION_STATUS_NOT_VALID}.
         * @param redirectUri If internet connectivity is being redirected (e.g., on a captive
         * portal), this is the destination the probes are being redirected to, otherwise
         * {@code null}.
         */
        public abstract void onValidationStatusChanged(@NonNull DataNetwork dataNetwork,
                @ValidationStatus int status, @Nullable Uri redirectUri);

        /**
         * Called when data network suspended state changed.
         *
         * @param dataNetwork The data network.
         * @param suspended {@code true} if data is suspended.
         */
        public abstract void onSuspendedStateChanged(@NonNull DataNetwork dataNetwork,
                boolean suspended);

        /**
         * Called when network requests were failed to attach to the data network.
         *
         * @param dataNetwork The data network.
         * @param requestList The requests failed to attach.
         */
        public abstract void onAttachFailed(@NonNull DataNetwork dataNetwork,
                @NonNull NetworkRequestList requestList);

        /**
         * Called when data network enters {@link DisconnectedState}. Note this is only called
         * when the data network was previously connected. For setup data network failed,
         * {@link #onSetupDataFailed(DataNetwork, NetworkRequestList, int, long)} is called.
         *
         * @param dataNetwork The data network.
         * @param cause The disconnect cause.
         */
        public abstract void onDisconnected(@NonNull DataNetwork dataNetwork,
                @DataFailureCause int cause);

        /**
         * Called when handover between IWLAN and cellular network succeeded.
         *
         * @param dataNetwork The data network.
         */
        public abstract void onHandoverSucceeded(@NonNull DataNetwork dataNetwork);

        /**
         * Called when data network handover between IWLAN and cellular network failed.
         *
         * @param dataNetwork The data network.
         * @param cause The fail cause.
         * @param retryDurationMillis Network suggested retry time in milliseconds.
         * {@link Long#MAX_VALUE} indicates data retry should not occur.
         * {@link DataCallResponse#RETRY_DURATION_UNDEFINED} indicates network did not suggest any
         * retry duration.
         * @param handoverFailureMode The handover failure mode that determine the behavior of
         * how frameworks should handle the handover failure.
         */
        public abstract void onHandoverFailed(@NonNull DataNetwork dataNetwork,
                @DataFailureCause int cause, long retryDurationMillis,
                @HandoverFailureMode int handoverFailureMode);

        /**
         * Called when data network link status (i.e. RRC state) changed.
         *
         * @param dataNetwork The data network.
         * @param linkStatus The link status (i.e. RRC state).
         */
        public abstract void onLinkStatusChanged(@NonNull DataNetwork dataNetwork,
                @LinkStatus int linkStatus);

        /**
         * Called when PCO data changed.
         *
         * @param dataNetwork The data network.
         */
        public abstract void onPcoDataChanged(@NonNull DataNetwork dataNetwork);

        /**
         * Called when network capabilities changed.
         *
         * @param dataNetwork The data network.
         */
        public abstract void onNetworkCapabilitiesChanged(@NonNull DataNetwork dataNetwork);

        /**
         * Called when attempt to tear down a data network
         *
         * @param dataNetwork The data network.
         */
        public abstract void onTrackNetworkUnwanted(@NonNull DataNetwork dataNetwork);
    }

    /**
     * Constructor
     *
     * @param phone The phone instance.
     * @param looper The looper to be used by the state machine. Currently the handler thread is the
     * phone process's main thread.
     * @param dataServiceManagers Data service managers.
     * @param dataProfile The data profile for establishing the data network.
     * @param networkRequestList The initial network requests attached to this data network.
     * @param transport The initial transport of the data network.
     * @param dataAllowedReason The reason that why setting up this data network is allowed.
     * @param callback The callback to receives data network state update.
     */
    public DataNetwork(@NonNull Phone phone, @NonNull Looper looper,
            @NonNull SparseArray<DataServiceManager> dataServiceManagers,
            @NonNull DataProfile dataProfile,
            @NonNull NetworkRequestList networkRequestList,
            @TransportType int transport,
            @NonNull DataAllowedReason dataAllowedReason,
            @NonNull DataNetworkCallback callback) {
        super("DataNetwork", looper);
        // State machine should be initialized at the top of constructor. log() can be only used
        // after state machine initialized (because getCurrentState() crashes if state machine has
        // not started.)
        initializeStateMachine();

        mPhone = phone;
        mSubId = phone.getSubId();
        mRil = mPhone.mCi;
        mLinkProperties = new LinkProperties();
        mDataServiceManagers = dataServiceManagers;
        mAccessNetworksManager = phone.getAccessNetworksManager();
        mVcnManager = mPhone.getContext().getSystemService(VcnManager.class);
        mDataNetworkController = phone.getDataNetworkController();
        mDataNetworkController.registerDataNetworkControllerCallback(
                new DataNetworkController.DataNetworkControllerCallback(getHandler()::post) {
                    @Override
                    public void onSubscriptionPlanOverride() {
                        sendMessage(EVENT_SUBSCRIPTION_PLAN_OVERRIDE);
                    }});
        mDataConfigManager = mDataNetworkController.getDataConfigManager();
        mDataCallSessionStats = new DataCallSessionStats(mPhone);
        mDataNetworkCallback = callback;
        mDataProfile = dataProfile;
        if (dataProfile.getTrafficDescriptor() != null) {
            // The initial traffic descriptor is from the data profile. After that traffic
            // descriptors will be updated by modem through setup data call response and data call
            // list changed event.
            mTrafficDescriptors.add(dataProfile.getTrafficDescriptor());
        }
        mTransport = transport;
        mDataAllowedReason = dataAllowedReason;
        dataProfile.setLastSetupTimestamp(SystemClock.elapsedRealtime());
        mAttachedNetworkRequestList.addAll(networkRequestList);
        mCid.put(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, INVALID_CID);
        mCid.put(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, INVALID_CID);
        mTcpBufferSizes = mDataConfigManager.getDefaultTcpConfigString();
        mTelephonyDisplayInfo = mPhone.getDisplayInfoController().getTelephonyDisplayInfo();

        for (TelephonyNetworkRequest networkRequest : networkRequestList) {
            networkRequest.setAttachedNetwork(DataNetwork.this);
            networkRequest.setState(TelephonyNetworkRequest.REQUEST_STATE_SATISFIED);
        }

        // Update the capabilities in the constructor is to make sure the data network has initial
        // capability immediately after created. Doing this connecting state creates the window that
        // DataNetworkController might check if existing data network's capability can satisfy the
        // next network request within this window.
        updateNetworkCapabilities();
    }

    /**
     * Initialize and start the state machine.
     */
    private void initializeStateMachine() {
        addState(mDefaultState);
        addState(mConnectingState, mDefaultState);
        addState(mConnectedState, mDefaultState);
        addState(mHandoverState, mDefaultState);
        addState(mDisconnectingState, mDefaultState);
        addState(mDisconnectedState, mDefaultState);
        setInitialState(mConnectingState);
        start();
    }

    /**
     * @return {@code true} if 464xlat should be skipped.
     */
    private boolean shouldSkip464Xlat() {
        if (mDataProfile.getApnSetting() != null) {
            switch (mDataProfile.getApnSetting().getSkip464Xlat()) {
                case Telephony.Carriers.SKIP_464XLAT_ENABLE:
                    return true;
                case Telephony.Carriers.SKIP_464XLAT_DISABLE:
                    return false;
                case Telephony.Carriers.SKIP_464XLAT_DEFAULT:
                default:
                    break;
            }
        }

        // As default, return true if ims and no internet
        final NetworkCapabilities nc = getNetworkCapabilities();
        return nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
                && !nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
    }

    /**
     * Create the telephony network agent.
     *
     * @return The telephony network agent.
     */
    private @NonNull TelephonyNetworkAgent createNetworkAgent() {
        final NetworkAgentConfig.Builder configBuilder = new NetworkAgentConfig.Builder();
        configBuilder.setLegacyType(ConnectivityManager.TYPE_MOBILE);
        configBuilder.setLegacyTypeName("MOBILE");
        int networkType = getDataNetworkType();
        configBuilder.setLegacySubType(networkType);
        configBuilder.setLegacySubTypeName(TelephonyManager.getNetworkTypeName(networkType));
        if (mDataProfile.getApnSetting() != null) {
            configBuilder.setLegacyExtraInfo(mDataProfile.getApnSetting().getApnName());
        }

        final CarrierSignalAgent carrierSignalAgent = mPhone.getCarrierSignalAgent();
        if (carrierSignalAgent.hasRegisteredReceivers(TelephonyManager
                .ACTION_CARRIER_SIGNAL_REDIRECTED)) {
            // carrierSignal Receivers will place the carrier-specific provisioning notification
            configBuilder.setProvisioningNotificationEnabled(false);
        }

        // Fill the IMSI
        final String subscriberId = mPhone.getSubscriberId();
        if (!TextUtils.isEmpty(subscriberId)) {
            configBuilder.setSubscriberId(subscriberId);
        }

        // set skip464xlat if it is not default otherwise
        if (shouldSkip464Xlat()) {
            configBuilder.setNat64DetectionEnabled(false);
        }

        final NetworkFactory factory = PhoneFactory.getNetworkFactory(
                mPhone.getPhoneId());
        final NetworkProvider provider = (null == factory) ? null : factory.getProvider();

        mNetworkScore = getNetworkScore();
        return new TelephonyNetworkAgent(mPhone, getHandler().getLooper(), this,
                new NetworkScore.Builder().setLegacyInt(mNetworkScore).build(),
                configBuilder.build(), provider,
                new TelephonyNetworkAgentCallback(getHandler()::post) {
                    @Override
                    public void onValidationStatus(@ValidationStatus int status,
                            @Nullable Uri redirectUri) {
                        mDataNetworkCallback.invokeFromExecutor(
                                () -> mDataNetworkCallback.onValidationStatusChanged(
                                        DataNetwork.this, status, redirectUri));
                    }
                });
    }

    /**
     * The default state. Any events that were not handled by the child states fallback to this
     * state.
     *
     * @see DataNetwork for the state machine diagram.
     */
    private final class DefaultState extends State {
        @Override
        public void enter() {
            logv("Registering all events.");
            mDataConfigManager.registerForConfigUpdate(getHandler(), EVENT_DATA_CONFIG_UPDATED);
            mRil.registerForPcoData(getHandler(), EVENT_PCO_DATA_RECEIVED, null);
            mPhone.getDisplayInfoController().registerForTelephonyDisplayInfoChanged(
                    getHandler(), EVENT_DISPLAY_INFO_CHANGED, null);
            mPhone.getServiceStateTracker().registerForServiceStateChanged(getHandler(),
                    EVENT_SERVICE_STATE_CHANGED);
            for (int transport : mAccessNetworksManager.getAvailableTransports()) {
                mDataServiceManagers.get(transport)
                        .registerForDataCallListChanged(getHandler(), EVENT_DATA_STATE_CHANGED);
            }
            mPhone.getCarrierPrivilegesTracker().registerCarrierPrivilegesListener(getHandler(),
                    EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED, null);

            mPhone.getServiceStateTracker().registerForCssIndicatorChanged(
                    getHandler(), EVENT_CSS_INDICATOR_CHANGED, null);
            mPhone.getCallTracker().registerForVoiceCallStarted(
                    getHandler(), EVENT_VOICE_CALL_STARTED, null);
            mPhone.getCallTracker().registerForVoiceCallEnded(
                    getHandler(), EVENT_VOICE_CALL_ENDED, null);
            // Check null for devices not supporting FEATURE_TELEPHONY_IMS.
            if (mPhone.getImsPhone() != null) {
                mPhone.getImsPhone().getCallTracker().registerForVoiceCallStarted(
                        getHandler(), EVENT_VOICE_CALL_STARTED, null);
                mPhone.getImsPhone().getCallTracker().registerForVoiceCallEnded(
                        getHandler(), EVENT_VOICE_CALL_ENDED, null);
            }

            // Only add symmetric code here, for example, registering and unregistering.
            // DefaultState.enter() is the starting point in the life cycle of the DataNetwork,
            // and DefaultState.exit() is the end. For non-symmetric initializing works, put them
            // in ConnectingState.enter().
        }

        @Override
        public void exit() {
            logv("Unregistering all events.");
            // Check null for devices not supporting FEATURE_TELEPHONY_IMS.
            if (mPhone.getImsPhone() != null) {
                mPhone.getImsPhone().getCallTracker().unregisterForVoiceCallStarted(getHandler());
                mPhone.getImsPhone().getCallTracker().unregisterForVoiceCallEnded(getHandler());
            }
            mPhone.getCallTracker().unregisterForVoiceCallStarted(getHandler());
            mPhone.getCallTracker().unregisterForVoiceCallEnded(getHandler());

            mPhone.getServiceStateTracker().unregisterForCssIndicatorChanged(getHandler());
            mPhone.getCarrierPrivilegesTracker().unregisterCarrierPrivilegesListener(getHandler());
            for (int transport : mAccessNetworksManager.getAvailableTransports()) {
                mDataServiceManagers.get(transport)
                        .unregisterForDataCallListChanged(getHandler());
            }
            mPhone.getServiceStateTracker().unregisterForServiceStateChanged(getHandler());
            mPhone.getDisplayInfoController().unregisterForTelephonyDisplayInfoChanged(
                    getHandler());
            mDataConfigManager.unregisterForConfigUpdate(getHandler());
            mRil.unregisterForPcoData(getHandler());
        }

        @Override
        public boolean processMessage(Message msg) {
            switch (msg.what) {
                case EVENT_DATA_CONFIG_UPDATED:
                    onDataConfigUpdated();
                    break;
                case EVENT_SERVICE_STATE_CHANGED: {
                    mDataCallSessionStats.onDrsOrRatChanged(getDataNetworkType());
                    updateSuspendState();
                    updateNetworkCapabilities();
                    break;
                }
                case EVENT_ATTACH_NETWORK_REQUEST: {
                    onAttachNetworkRequests((NetworkRequestList) msg.obj);
                    updateNetworkScore();
                    break;
                }
                case EVENT_DETACH_NETWORK_REQUEST: {
                    onDetachNetworkRequest((TelephonyNetworkRequest) msg.obj);
                    updateNetworkScore();
                    break;
                }
                case EVENT_DETACH_ALL_NETWORK_REQUESTS: {
                    for (TelephonyNetworkRequest networkRequest : mAttachedNetworkRequestList) {
                        networkRequest.setState(TelephonyNetworkRequest.REQUEST_STATE_UNSATISFIED);
                        networkRequest.setAttachedNetwork(null);
                    }
                    log("All network requests detached.");
                    mAttachedNetworkRequestList.clear();
                    break;
                }
                case EVENT_DATA_STATE_CHANGED: {
                    AsyncResult ar = (AsyncResult) msg.obj;
                    int transport = (int) ar.userObj;
                    onDataStateChanged(transport, (List<DataCallResponse>) ar.result);
                    break;
                }
                case EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED: {
                    AsyncResult asyncResult = (AsyncResult) msg.obj;
                    int[] administratorUids = (int[]) asyncResult.result;
                    mAdministratorUids = Arrays.copyOf(administratorUids, administratorUids.length);
                    updateNetworkCapabilities();
                    break;
                }
                case EVENT_PCO_DATA_RECEIVED: {
                    AsyncResult ar = (AsyncResult) msg.obj;
                    onPcoDataReceived((PcoData) ar.result);
                    break;
                }
                case EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED:
                case EVENT_TEAR_DOWN_NETWORK:
                case EVENT_STUCK_IN_TRANSIENT_STATE:
                case EVENT_DISPLAY_INFO_CHANGED:
                case EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET:
                case EVENT_CSS_INDICATOR_CHANGED:
                case EVENT_VOICE_CALL_STARTED:
                case EVENT_VOICE_CALL_ENDED:
                    // Ignore the events when not in the correct state.
                    log("Ignored " + eventToString(msg.what));
                    break;
                case EVENT_START_HANDOVER:
                    log("Ignore the handover to " + AccessNetworkConstants
                            .transportTypeToString(msg.arg1) + " request.");
                    break;
                default:
                    loge("Unhandled event " + eventToString(msg.what));
                    break;
            }
            return HANDLED;
        }
    }

    /**
     * The connecting state. This is the initial state of a data network.
     *
     * @see DataNetwork for the state machine diagram.
     */
    private final class ConnectingState extends State {
        @Override
        public void enter() {
            sendMessageDelayed(EVENT_STUCK_IN_TRANSIENT_STATE,
                    mDataConfigManager.getAnomalyNetworkConnectingTimeoutMs());
            mNetworkAgent = createNetworkAgent();
            mInitialNetworkAgentId = mNetworkAgent.getId();
            mLogTag = "DN-" + mInitialNetworkAgentId + "-"
                    + ((mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) ? "C" : "I");

            // Get carrier config package uid. Note that this uid will not change through the life
            // cycle of this data network. So there is no need to listen to the change event.
            mCarrierServicePackageUid = mPhone.getCarrierPrivilegesTracker()
                    .getCarrierServicePackageUid();

            notifyPreciseDataConnectionState();
            if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
                // Defer setupData until we get the PDU session ID response
                allocatePduSessionId();
                return;
            }

            setupData();
        }

        @Override
        public void exit() {
            removeMessages(EVENT_STUCK_IN_TRANSIENT_STATE);
        }

        @Override
        public boolean processMessage(Message msg) {
            logv("event=" + eventToString(msg.what));
            switch (msg.what) {
                case EVENT_ALLOCATE_PDU_SESSION_ID_RESPONSE:
                    AsyncResult ar = (AsyncResult) msg.obj;
                    if (ar.exception == null) {
                        mPduSessionId = (int) ar.result;
                        log("Set PDU session id to " + mPduSessionId);
                    } else {
                        loge("Failed to allocate PDU session id. e=" + ar.exception);
                    }
                    setupData();
                    break;
                case EVENT_SETUP_DATA_NETWORK_RESPONSE:
                    int resultCode = msg.arg1;
                    DataCallResponse dataCallResponse =
                            msg.getData().getParcelable(DataServiceManager.DATA_CALL_RESPONSE);
                    onSetupResponse(resultCode, dataCallResponse);
                    break;
                case EVENT_START_HANDOVER:
                case EVENT_TEAR_DOWN_NETWORK:
                case EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET:
                    // Defer the request until connected or disconnected.
                    log("Defer message " + eventToString(msg.what));
                    deferMessage(msg);
                    break;
                case EVENT_STUCK_IN_TRANSIENT_STATE:
                    reportAnomaly("Data network stuck in connecting state for "
                            + TimeUnit.MILLISECONDS.toSeconds(
                            mDataConfigManager.getAnomalyNetworkConnectingTimeoutMs())
                            + " seconds.", "58c56403-7ea7-4e56-a0c7-e467114d09b8");
                    // Setup data failed. Use the retry logic defined in
                    // CarrierConfigManager.KEY_TELEPHONY_DATA_SETUP_RETRY_RULES_STRING_ARRAY.
                    mRetryDelayMillis = DataCallResponse.RETRY_DURATION_UNDEFINED;
                    mFailCause = DataFailCause.NO_RETRY_FAILURE;
                    transitionTo(mDisconnectedState);
                    break;
                default:
                    return NOT_HANDLED;
            }
            return HANDLED;
        }
    }

    /**
     * The connected state. This is the state when data network becomes usable.
     *
     * @see DataNetwork for the state machine diagram.
     */
    private final class ConnectedState extends State {
        @Override
        public void enter() {
            // Note that reaching here could mean from connecting -> connected, or from
            // handover -> connected.
            if (!mEverConnected) {
                // Transited from ConnectingState
                log("network connected.");
                mEverConnected = true;
                mNetworkAgent.markConnected();
                mDataNetworkCallback.invokeFromExecutor(
                        () -> mDataNetworkCallback.onConnected(DataNetwork.this));

                mQosCallbackTracker = new QosCallbackTracker(mNetworkAgent, mPhone);
                mQosCallbackTracker.updateSessions(mQosBearerSessions);
                mKeepaliveTracker = new KeepaliveTracker(mPhone,
                        getHandler().getLooper(), DataNetwork.this, mNetworkAgent);
                if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
                    registerForWwanEvents();
                }

                // Create the VCN policy changed listener. When the policy changed, we might need
                // to tear down the VCN-managed network.
                if (mVcnManager != null) {
                    mVcnPolicyChangeListener = () -> {
                        log("VCN policy changed.");
                        if (mVcnManager.applyVcnNetworkPolicy(mNetworkCapabilities, mLinkProperties)
                                .isTeardownRequested()) {
                            tearDown(TEAR_DOWN_REASON_VCN_REQUESTED);
                        } else {
                            updateNetworkCapabilities();
                        }
                    };
                    mVcnManager.addVcnNetworkPolicyChangeListener(
                            getHandler()::post, mVcnPolicyChangeListener);
                }
            }

            // If we've ever received PCO data before connected, now it's the time to
            // process it.
            mPcoData.getOrDefault(mCid.get(mTransport), Collections.emptyMap())
                    .forEach((pcoId, pcoData) -> {
                        onPcoDataChanged(pcoData);
                    });

            notifyPreciseDataConnectionState();
            updateSuspendState();
        }

        @Override
        public boolean processMessage(Message msg) {
            logv("event=" + eventToString(msg.what));
            switch (msg.what) {
                case EVENT_TEAR_DOWN_NETWORK:
                    if (mInvokedDataDeactivation) {
                        log("Ignore tear down request because network is being torn down.");
                        break;
                    }

                    int tearDownReason = msg.arg1;
                    // If the tear down request is from upper layer, for example, IMS service
                    // releases network request, we don't need to delay. The purpose of the delay
                    // is to have IMS service have time to perform IMS de-registration, so if this
                    // request is from IMS service itself, that means IMS service is already aware
                    // of the tear down. So there is no need to delay in this case.
                    if (tearDownReason != TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED
                            && shouldDelayImsTearDown()) {
                        logl("Delay IMS tear down until call ends. reason="
                                + tearDownReasonToString(tearDownReason));
                        break;
                    }

                    removeMessages(EVENT_TEAR_DOWN_NETWORK);
                    removeDeferredMessages(EVENT_TEAR_DOWN_NETWORK);
                    transitionTo(mDisconnectingState);
                    onTearDown(tearDownReason);
                    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_DISPLAY_INFO_CHANGED:
                    onDisplayInfoChanged();
                    break;
                case EVENT_START_HANDOVER:
                    onStartHandover(msg.arg1, (DataHandoverRetryEntry) msg.obj);
                    break;
                case EVENT_SUBSCRIPTION_PLAN_OVERRIDE:
                    updateMeteredAndCongested();
                    break;
                case EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE:
                    int resultCode = msg.arg1;
                    onDeactivateResponse(resultCode);
                    break;
                case EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET:
                    transitionTo(mDisconnectingState);
                    sendMessageDelayed(EVENT_TEAR_DOWN_NETWORK, msg.arg1, msg.arg2);
                    break;
                case EVENT_VOICE_CALL_STARTED:
                case EVENT_VOICE_CALL_ENDED:
                case EVENT_CSS_INDICATOR_CHANGED:
                    updateSuspendState();
                    updateNetworkCapabilities();
                    break;
                default:
                    return NOT_HANDLED;
            }
            return HANDLED;
        }
    }

    /**
     * The handover state. This is the state when data network handover between IWLAN and cellular.
     *
     * @see DataNetwork for the state machine diagram.
     */
    private final class HandoverState extends State {
        @Override
        public void enter() {
            sendMessageDelayed(EVENT_STUCK_IN_TRANSIENT_STATE,
                    mDataConfigManager.getNetworkHandoverTimeoutMs());
            notifyPreciseDataConnectionState();
        }

        @Override
        public void exit() {
            removeMessages(EVENT_STUCK_IN_TRANSIENT_STATE);
        }

        @Override
        public boolean processMessage(Message msg) {
            logv("event=" + eventToString(msg.what));
            switch (msg.what) {
                case EVENT_DATA_STATE_CHANGED:
                    // The data call list changed event should be conditionally deferred.
                    // Otherwise the deferred message might be incorrectly treated as "disconnected"
                    // signal. So we only defer the related data call list changed event, and drop
                    // the unrelated.
                    if (shouldDeferDataStateChangedEvent(msg)) {
                        log("Defer message " + eventToString(msg.what));
                        deferMessage(msg);
                    }
                    break;
                case EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET:
                case EVENT_DISPLAY_INFO_CHANGED:
                case EVENT_TEAR_DOWN_NETWORK:
                case EVENT_CSS_INDICATOR_CHANGED:
                case EVENT_VOICE_CALL_ENDED:
                case EVENT_VOICE_CALL_STARTED:
                    // Defer the request until handover succeeds or fails.
                    log("Defer message " + eventToString(msg.what));
                    deferMessage(msg);
                    break;
                case EVENT_HANDOVER_RESPONSE:
                    int resultCode = msg.arg1;
                    DataCallResponse dataCallResponse =
                            msg.getData().getParcelable(DataServiceManager.DATA_CALL_RESPONSE);
                    onHandoverResponse(resultCode, dataCallResponse,
                            (DataHandoverRetryEntry) msg.obj);
                    break;
                case EVENT_STUCK_IN_TRANSIENT_STATE:
                    reportAnomaly("Data service did not respond the handover request within "
                            + TimeUnit.MILLISECONDS.toSeconds(
                            mDataConfigManager.getNetworkHandoverTimeoutMs()) + " seconds.",
                            "1afe68cb-8b41-4964-a737-4f34372429ea");

                    // Handover failed. Use the retry logic defined in
                    // CarrierConfigManager.KEY_TELEPHONY_DATA_HANDOVER_RETRY_RULES_STRING_ARRAY.
                    long retry = DataCallResponse.RETRY_DURATION_UNDEFINED;
                    int handoverFailureMode =
                            DataCallResponse.HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL;
                    mFailCause = DataFailCause.ERROR_UNSPECIFIED;
                    mDataNetworkCallback.invokeFromExecutor(
                            () -> mDataNetworkCallback.onHandoverFailed(DataNetwork.this,
                                    mFailCause, retry, handoverFailureMode));
                    // No matter handover succeeded or not, transit back to connected state.
                    transitionTo(mConnectedState);
                    break;
                default:
                    return NOT_HANDLED;
            }
            return HANDLED;
        }

        /**
         * Check if the data call list changed event should be deferred or dropped when handover
         * is in progress.
         *
         * @param msg The data call list changed message.
         *
         * @return {@code true} if the message should be deferred.
         */
        private boolean shouldDeferDataStateChangedEvent(@NonNull Message msg) {
            // The data call list changed event should be conditionally deferred.
            // Otherwise the deferred message might be incorrectly treated as "disconnected"
            // signal. So we only defer the related data call list changed event, and drop
            // the unrelated.
            AsyncResult ar = (AsyncResult) msg.obj;
            int transport = (int) ar.userObj;
            List<DataCallResponse> responseList = (List<DataCallResponse>) ar.result;
            if (transport != mTransport) {
                log("Dropped unrelated " + AccessNetworkConstants.transportTypeToString(transport)
                        + " data call list changed event. " + responseList);
                return false;
            }

            // Check if the data call list changed event are related to the current data network.
            boolean related = responseList.stream().anyMatch(
                    r -> mCid.get(mTransport) == r.getId());
            if (related) {
                log("Deferred the related data call list changed event." + responseList);
            } else {
                log("Dropped unrelated data call list changed event. " + responseList);
            }
            return related;
        }
    }

    /**
     * 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. This state is particular useful for IMS graceful tear down, where
     * the network enters disconnecting state while waiting for IMS de-registration signal.
     *
     * @see DataNetwork for the state machine diagram.
     */
    private final class DisconnectingState extends State {
        @Override
        public void enter() {
            sendMessageDelayed(EVENT_STUCK_IN_TRANSIENT_STATE,
                    mDataConfigManager.getAnomalyNetworkDisconnectingTimeoutMs());
            notifyPreciseDataConnectionState();
        }

        @Override
        public void exit() {
            removeMessages(EVENT_STUCK_IN_TRANSIENT_STATE);
        }

        @Override
        public boolean processMessage(Message msg) {
            logv("event=" + eventToString(msg.what));
            switch (msg.what) {
                case EVENT_TEAR_DOWN_NETWORK:
                    if (mInvokedDataDeactivation) {
                        log("Ignore tear down request because network is being torn down.");
                        break;
                    }
                    removeMessages(EVENT_TEAR_DOWN_NETWORK);
                    removeDeferredMessages(EVENT_TEAR_DOWN_NETWORK);
                    onTearDown(msg.arg1);
                    break;
                case EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE:
                    int resultCode = msg.arg1;
                    onDeactivateResponse(resultCode);
                    break;
                case EVENT_STUCK_IN_TRANSIENT_STATE:
                    // After frameworks issues deactivate data call request, RIL should report
                    // data disconnected through data call list changed event subsequently.
                    reportAnomaly("RIL did not send data call list changed event after "
                            + "deactivate data call request within "
                            + TimeUnit.MILLISECONDS.toSeconds(
                            mDataConfigManager.getAnomalyNetworkDisconnectingTimeoutMs())
                            + " seconds.", "d0e4fa1c-c57b-4ba5-b4b6-8955487012cc");
                    mFailCause = DataFailCause.LOST_CONNECTION;
                    transitionTo(mDisconnectedState);
                    break;
                case EVENT_DISPLAY_INFO_CHANGED:
                    onDisplayInfoChanged();
                    break;
                case EVENT_CSS_INDICATOR_CHANGED:
                case EVENT_VOICE_CALL_STARTED:
                case EVENT_VOICE_CALL_ENDED:
                    updateSuspendState();
                    updateNetworkCapabilities();
                    break;
                default:
                    return NOT_HANDLED;
            }
            return HANDLED;
        }
    }

    /**
     * The disconnected state. This is the final state of a data network.
     *
     * @see DataNetwork for the state machine diagram.
     */
    private final class DisconnectedState extends State {
        @Override
        public void enter() {
            logl("Data network disconnected. mEverConnected=" + mEverConnected);
            // Preserve the list for onSetupDataFailed callback, because we need to pass that list
            // back to DataNetworkController, but after EVENT_DETACH_ALL_NETWORK_REQUESTS gets
            // processed, the network request list would become empty.
            NetworkRequestList requestList = new NetworkRequestList(mAttachedNetworkRequestList);

            // The detach all network requests must be the last message to handle.
            sendMessage(EVENT_DETACH_ALL_NETWORK_REQUESTS);
            // Gracefully handle all the un-processed events then quit the state machine.
            // quit() throws a QUIT event to the end of message queue. All the events before quit()
            // will be processed. Events after quit() will not be processed.
            quit();

            //************************************************************//
            // DO NOT POST ANY EVENTS AFTER HERE.                         //
            // THE STATE MACHINE WONT PROCESS EVENTS AFTER QUIT.          //
            // ONLY CLEANUP SHOULD BE PERFORMED AFTER THIS.               //
            //************************************************************//

            if (mEverConnected) {
                mDataNetworkCallback.invokeFromExecutor(() -> mDataNetworkCallback
                        .onDisconnected(DataNetwork.this, mFailCause));
                if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
                    unregisterForWwanEvents();
                }
            } else {
                mDataNetworkCallback.invokeFromExecutor(() -> mDataNetworkCallback
                        .onSetupDataFailed(DataNetwork.this,
                                requestList, mFailCause, mRetryDelayMillis));
            }
            notifyPreciseDataConnectionState();
            mNetworkAgent.unregister();
            mDataCallSessionStats.onDataCallDisconnected(mFailCause);

            if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN
                    && mPduSessionId != DataCallResponse.PDU_SESSION_ID_NOT_SET) {
                mRil.releasePduSessionId(null, mPduSessionId);
            }

            if (mVcnManager != null && mVcnPolicyChangeListener != null) {
                mVcnManager.removeVcnNetworkPolicyChangeListener(mVcnPolicyChangeListener);
            }
        }

        @Override
        public boolean processMessage(Message msg) {
            logv("event=" + eventToString(msg.what));
            return NOT_HANDLED;
        }
    }

    /**
     * Register for events that can only happen on cellular networks.
     */
    private void registerForWwanEvents() {
        registerForBandwidthUpdate();
        mKeepaliveTracker.registerForKeepaliveStatus();
    }

    /**
     * Unregister for events that can only happen on cellular networks.
     */
    private void unregisterForWwanEvents() {
        unregisterForBandwidthUpdate();
        mKeepaliveTracker.unregisterForKeepaliveStatus();
    }

    @Override
    protected void unhandledMessage(Message msg) {
        IState state = getCurrentState();
        loge("Unhandled message " + msg.what + " in state "
                + (state == null ? "null" : state.getName()));
    }

    /**
     * Attempt to attach the network request list to this data network. Whether the network can
     * satisfy the request or not will be checked when EVENT_ATTACH_NETWORK_REQUEST is processed.
     * If the request can't be attached, {@link DataNetworkCallback#onAttachFailed(
     * DataNetwork, NetworkRequestList)}.
     *
     * @param requestList Network request list to attach.
     * @return {@code false} if the network is already disconnected. {@code true} means the request
     * has been scheduled to attach to the network. If attach succeeds, the network request's state
     * will be set to {@link TelephonyNetworkRequest#REQUEST_STATE_SATISFIED}. If failed, the
     * callback {@link DataNetworkCallback#onAttachFailed(DataNetwork, NetworkRequestList)} will
     * be called.
     */
    public boolean attachNetworkRequests(@NonNull NetworkRequestList requestList) {
        // If the network is already ended, we still attach the network request to the data network,
        // so it can be retried later by data network controller.
        if (getCurrentState() == null || isDisconnected()) {
            // The state machine has already stopped. This is due to data network is disconnected.
            return false;
        }
        sendMessage(obtainMessage(EVENT_ATTACH_NETWORK_REQUEST, requestList));
        return true;
    }

    /**
     * Called when attaching network request list to this data network.
     *
     * @param requestList Network request list to attach.
     */
    public void onAttachNetworkRequests(@NonNull NetworkRequestList requestList) {
        NetworkRequestList failedList = new NetworkRequestList();
        for (TelephonyNetworkRequest networkRequest : requestList) {
            if (!mDataNetworkController.isNetworkRequestExisting(networkRequest)) {
                failedList.add(networkRequest);
                log("Attached failed. Network request was already removed. " + networkRequest);
            } else if (!networkRequest.canBeSatisfiedBy(getNetworkCapabilities())) {
                failedList.add(networkRequest);
                log("Attached failed. Cannot satisfy the network request "
                        + networkRequest);
            } else {
                mAttachedNetworkRequestList.add(networkRequest);
                networkRequest.setAttachedNetwork(DataNetwork.this);
                networkRequest.setState(
                        TelephonyNetworkRequest.REQUEST_STATE_SATISFIED);
                log("Successfully attached network request " + networkRequest);
            }
        }
        if (failedList.size() > 0) {
            mDataNetworkCallback.invokeFromExecutor(() -> mDataNetworkCallback
                    .onAttachFailed(DataNetwork.this, failedList));
        }
    }

    /**
     * Called when detaching the network request from this data network.
     *
     * @param networkRequest Network request to detach.
     */
    private void onDetachNetworkRequest(@NonNull TelephonyNetworkRequest networkRequest) {
        mAttachedNetworkRequestList.remove(networkRequest);
        networkRequest.setState(TelephonyNetworkRequest.REQUEST_STATE_UNSATISFIED);
        networkRequest.setAttachedNetwork(null);

        if (mAttachedNetworkRequestList.isEmpty()) {
            log("All network requests are detached.");

            // If there is no network request attached, and we are not preferred data phone, then
            // this detach is likely due to temp DDS switch. We should tear down the network when
            // all requests are detached so the other network on preferred data sub can be
            // established properly.
            int preferredDataPhoneId = PhoneSwitcher.getInstance().getPreferredDataPhoneId();
            if (preferredDataPhoneId != SubscriptionManager.INVALID_PHONE_INDEX
                    && preferredDataPhoneId != mPhone.getPhoneId()) {
                tearDown(TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED);
            }
        }
    }

    /**
     * Detach the network request from this data network. Note that this will not tear down the
     * network.
     *
     * @param networkRequest Network request to detach.
     */
    public void detachNetworkRequest(@NonNull TelephonyNetworkRequest networkRequest) {
        if (getCurrentState() == null || isDisconnected()) {
            return;
        }
        sendMessage(obtainMessage(EVENT_DETACH_NETWORK_REQUEST, networkRequest));
    }

    /**
     * Register for bandwidth update.
     */
    private void registerForBandwidthUpdate() {
        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) {
            if (mLinkBandwidthEstimatorCallback == null) {
                mLinkBandwidthEstimatorCallback =
                        new LinkBandwidthEstimatorCallback(getHandler()::post) {
                            @Override
                            public void onBandwidthChanged(int uplinkBandwidthKbps,
                                    int downlinkBandwidthKbps) {
                                if (isConnected()) {
                                    onBandwidthUpdated(uplinkBandwidthKbps, downlinkBandwidthKbps);
                                }
                            }
                        };
                mPhone.getLinkBandwidthEstimator().registerCallback(
                        mLinkBandwidthEstimatorCallback);
            }
        } else {
            loge("Invalid bandwidth source configuration: " + bandwidthEstimateSource);
        }
    }

    /**
     * Unregister bandwidth update.
     */
    private void unregisterForBandwidthUpdate() {
        int bandwidthEstimateSource = mDataConfigManager.getBandwidthEstimateSource();
        if (bandwidthEstimateSource == BANDWIDTH_SOURCE_MODEM) {
            mPhone.mCi.unregisterForLceInfo(getHandler());
        } else if (bandwidthEstimateSource == BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR) {
            if (mLinkBandwidthEstimatorCallback != null) {
                mPhone.getLinkBandwidthEstimator()
                        .unregisterCallback(mLinkBandwidthEstimatorCallback);
                mLinkBandwidthEstimatorCallback = null;
            }
        } else {
            loge("Invalid bandwidth source configuration: " + bandwidthEstimateSource);
        }
    }

    /**
     * Remove network requests that can't be satisfied anymore.
     */
    private void removeUnsatisfiedNetworkRequests() {
        for (TelephonyNetworkRequest networkRequest : mAttachedNetworkRequestList) {
            if (!networkRequest.canBeSatisfiedBy(mNetworkCapabilities)) {
                log("removeUnsatisfiedNetworkRequests: " + networkRequest
                        + " can't be satisfied anymore. Will be detached.");
                detachNetworkRequest(networkRequest);
            }
        }
    }

    /**
     * Check if the new link properties are compatible with the old link properties. For example,
     * if IP changes, that's considered incompatible.
     *
     * @param oldLinkProperties Old link properties.
     * @param newLinkProperties New Link properties.
     *
     * @return {@code true} if the new link properties is compatible with the old link properties.
     */
    private boolean isLinkPropertiesCompatible(@NonNull LinkProperties oldLinkProperties,
            @NonNull LinkProperties newLinkProperties) {
        if (Objects.equals(oldLinkProperties, newLinkProperties)) return true;

        if (!LinkPropertiesUtils.isIdenticalAddresses(oldLinkProperties, newLinkProperties)) {
            // If the same address type was removed and added we need to cleanup.
            LinkPropertiesUtils.CompareOrUpdateResult<Integer, LinkAddress> result =
                    new LinkPropertiesUtils.CompareOrUpdateResult<>(
                            oldLinkProperties.getLinkAddresses(),
                            newLinkProperties.getLinkAddresses(),
                            linkAddress -> Objects.hash(linkAddress.getAddress(),
                                    linkAddress.getPrefixLength(), linkAddress.getScope()));
            log("isLinkPropertiesCompatible: old=" + oldLinkProperties
                    + " new=" + newLinkProperties + " result=" + result);
            for (LinkAddress added : result.added) {
                for (LinkAddress removed : result.removed) {
                    if (NetUtils.addressTypeMatches(removed.getAddress(), added.getAddress())) {
                        return false;
                    }
                }
            }
        }

        return true;
    }

    /**
     * Check if there are immutable capabilities changed. The connectivity service is not able
     * to handle immutable capabilities changed, but in very rare scenarios, immutable capabilities
     * need to be changed dynamically, such as in setup data call response, modem responded with the
     * same cid. In that case, we need to merge the new capabilities into the existing data network.
     *
     * @param oldCapabilities The old network capabilities.
     * @param newCapabilities The new network capabilities.
     * @return {@code true} if there are immutable network capabilities changed.
     */
    private static boolean areImmutableCapabilitiesChanged(
            @NonNull NetworkCapabilities oldCapabilities,
            @NonNull NetworkCapabilities newCapabilities) {
        if (oldCapabilities == null
                || ArrayUtils.isEmpty(oldCapabilities.getCapabilities())) return false;

        // Remove mutable capabilities from both old and new capabilities, the remaining
        // capabilities would be immutable capabilities.
        List<Integer> oldImmutableCapabilities = Arrays.stream(oldCapabilities.getCapabilities())
                .boxed().collect(Collectors.toList());
        oldImmutableCapabilities.removeAll(MUTABLE_CAPABILITIES);
        List<Integer> newImmutableCapabilities = Arrays.stream(newCapabilities.getCapabilities())
                .boxed().collect(Collectors.toList());
        newImmutableCapabilities.removeAll(MUTABLE_CAPABILITIES);
        return oldImmutableCapabilities.size() != newImmutableCapabilities.size()
                || !oldImmutableCapabilities.containsAll(newImmutableCapabilities);
    }

    /**
     * Update the network capabilities.
     */
    private void updateNetworkCapabilities() {
        final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder()
                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
        boolean roaming = mPhone.getServiceState().getDataRoaming();

        builder.setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
                .setSubscriptionId(mSubId).build());
        builder.setSubscriptionIds(Collections.singleton(mSubId));

        ApnSetting apnSetting = mDataProfile.getApnSetting();

        if (apnSetting != null) {
            apnSetting.getApnTypes().stream()
                    .map(DataUtils::apnTypeToNetworkCapability)
                    .filter(cap -> cap >= 0)
                    .forEach(builder::addCapability);
            if (apnSetting.getApnTypes().contains(ApnSetting.TYPE_ENTERPRISE)) {
                builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
            }
        }

        // Once we set the MMTEL capability, we should never remove it because it's an immutable
        // capability defined by connectivity service. When the device enters from VoPS to non-VoPS,
        // we should perform grace tear down from data network controller if needed.
        if (mNetworkCapabilities != null
                && mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL)) {
            // Previous capability has MMTEL, so add it again.
            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL);
        } else {
            // Always add MMTEL capability on IMS network unless network explicitly indicates VoPS
            // not supported.
            if (mDataProfile.canSatisfy(NetworkCapabilities.NET_CAPABILITY_IMS)) {
                builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL);
                if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
                    NetworkRegistrationInfo nri = getNetworkRegistrationInfo();
                    if (nri != null) {
                        DataSpecificRegistrationInfo dsri = nri.getDataSpecificInfo();
                        // Check if the network is non-VoPS.
                        if (dsri != null && dsri.getVopsSupportInfo() != null
                                && !dsri.getVopsSupportInfo().isVopsSupported()) {
                            builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL);
                        }
                        log("updateNetworkCapabilities: dsri=" + dsri);
                    }
                }
            }
        }

        // Extract network capabilities from the traffic descriptor.
        for (TrafficDescriptor trafficDescriptor : mTrafficDescriptors) {
            try {
                if (trafficDescriptor.getOsAppId() == null) continue;
                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);
                        // Always add internet if TD contains enterprise.
                        builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
                        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));
            }
        }

        if (!mCongested) {
            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED);
        }

        if (mTempNotMeteredSupported && mTempNotMetered) {
            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED);
        }

        // Always start with NOT_VCN_MANAGED, then remove if VcnManager indicates this is part of a
        // VCN.
        builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
        final VcnNetworkPolicyResult vcnPolicy = getVcnPolicy(builder.build());
        if (vcnPolicy != null && !vcnPolicy.getNetworkCapabilities()
                .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)) {
            builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
        }

        if (!roaming) {
            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
        }

        if (!mSuspended) {
            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED);
        }

        if (mCarrierServicePackageUid != Process.INVALID_UID
                && ArrayUtils.contains(mAdministratorUids, mCarrierServicePackageUid)) {
            builder.setOwnerUid(mCarrierServicePackageUid);
            builder.setAllowedUids(Collections.singleton(mCarrierServicePackageUid));
        }
        builder.setAdministratorUids(mAdministratorUids);

        Set<Integer> meteredCapabilities = mDataConfigManager
                .getMeteredNetworkCapabilities(roaming).stream()
                .filter(cap -> mAccessNetworksManager.getPreferredTransportByNetworkCapability(cap)
                        == AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                .collect(Collectors.toSet());
        boolean unmeteredNetwork = meteredCapabilities.stream().noneMatch(
                Arrays.stream(builder.build().getCapabilities()).boxed()
                        .collect(Collectors.toSet())::contains);

        if (unmeteredNetwork) {
            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
        }

        // Always start with not-restricted, and then remove if needed.
        builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);

        // When data is disabled, or data roaming is disabled and the device is roaming, we need
        // to remove certain capabilities depending on scenarios.
        if (!mDataNetworkController.getDataSettingsManager().isDataEnabled()
                || (mPhone.getServiceState().getDataRoaming()
                && !mDataNetworkController.getDataSettingsManager().isDataRoamingEnabled())) {
            // If data is allowed because the request is a restricted network request, we need
            // to mark the network as restricted when data is disabled or data roaming is disabled
            // and the device is roaming. If we don't do that, non-privileged apps will be able
            // to use this network when data is disabled.
            if (mDataAllowedReason == DataAllowedReason.RESTRICTED_REQUEST) {
                builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
            } else if (mDataAllowedReason == DataAllowedReason.UNMETERED_USAGE
                    || mDataAllowedReason == DataAllowedReason.MMS_REQUEST
                    || mDataAllowedReason == DataAllowedReason.EMERGENCY_SUPL) {
                // If data is allowed due to unmetered usage, or MMS always-allowed, we need to
                // remove unrelated-but-metered capabilities.
                for (int capability : meteredCapabilities) {
                    // 1. If it's unmetered usage, remove all metered capabilities.
                    // 2. If it's MMS always-allowed, then remove all metered capabilities but MMS.
                    // 3/ If it's for emergency SUPL, then remove all metered capabilities but SUPL.
                    if ((capability == NetworkCapabilities.NET_CAPABILITY_MMS
                            && mDataAllowedReason == DataAllowedReason.MMS_REQUEST)
                            || (capability == NetworkCapabilities.NET_CAPABILITY_SUPL
                            && mDataAllowedReason == DataAllowedReason.EMERGENCY_SUPL)) {
                        // Not removing the capability for special uses.
                        continue;
                    }
                    builder.removeCapability(capability);
                }
            }
        }

        // If one of the capabilities are for special use, for example, IMS, CBS, then this
        // network should be restricted, regardless data is enabled or not.
        if (NetworkCapabilitiesUtils.inferRestrictedCapability(builder.build())
                || (vcnPolicy != null && !vcnPolicy.getNetworkCapabilities()
                        .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED))) {
            builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
        }

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

        NetworkCapabilities nc = builder.build();
        if (mNetworkCapabilities == null || mNetworkAgent == null) {
            // This is the first time when network capabilities is created. The agent is not created
            // at this time. Just return here. The network capabilities will be used when network
            // agent is created.
            mNetworkCapabilities = nc;
            logl("Initial capabilities " + mNetworkCapabilities);
            return;
        }

        if (!nc.equals(mNetworkCapabilities)) {
            // Check if we are changing the immutable capabilities. Note that we should be very
            // careful and limit the use cases of changing immutable capabilities. Connectivity
            // service would not close sockets for clients if a network request becomes
            // unsatisfiable.
            if (mEverConnected && areImmutableCapabilitiesChanged(mNetworkCapabilities, nc)
                    && (isConnected() || isHandoverInProgress())) {
                // Before connectivity service supports making all capabilities mutable, it is
                // suggested to de-register and re-register the network agent if it is needed to
                // add/remove immutable capabilities.
                logl("updateNetworkCapabilities: Immutable capabilities changed. Re-create the "
                        + "network agent. Attempted to change from " + mNetworkCapabilities + " to "
                        + nc);
                // Abandon the network agent because we are going to create a new one.
                mNetworkAgent.abandon();
                // Update the capabilities first so the new network agent would be created with the
                // new capabilities.
                mNetworkCapabilities = nc;
                mNetworkAgent = createNetworkAgent();
                mNetworkAgent.markConnected();
            } else {
                // Now we need to inform connectivity service and data network controller
                // about the capabilities changed.
                mNetworkCapabilities = nc;
                log("Capabilities changed to " + mNetworkCapabilities);
                mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
            }

            removeUnsatisfiedNetworkRequests();
            mDataNetworkCallback.invokeFromExecutor(() -> mDataNetworkCallback
                    .onNetworkCapabilitiesChanged(DataNetwork.this));
        } else {
            log("updateNetworkCapabilities: Capabilities not changed.");
        }
    }

    /**
     * @return The network capabilities of this data network.
     */
    public @NonNull NetworkCapabilities getNetworkCapabilities() {
        return mNetworkCapabilities;
    }

    /**
     * @return The link properties of this data network.
     */
    public @NonNull LinkProperties getLinkProperties() {
        return mLinkProperties;
    }

    /**
     * @return The data profile of this data network.
     */
    public @NonNull DataProfile getDataProfile() {
        return mDataProfile;
    }

    /**
     * Update data suspended state.
     */
    private void updateSuspendState() {
        if (isConnecting() || isDisconnected()) {
            // Return if not in the right state.
            return;
        }

        boolean newSuspendedState = false;
        // Get the uncombined service state directly.
        NetworkRegistrationInfo nri = getNetworkRegistrationInfo();
        if (nri == null) return;

        // Never set suspended for emergency apn. Emergency data connection
        // can work while device is not in service.
        if (mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)) {
            newSuspendedState = false;
            // If we are not in service, change to suspended.
        } else if (nri.getRegistrationState()
                != NetworkRegistrationInfo.REGISTRATION_STATE_HOME
                && nri.getRegistrationState()
                != NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING) {
            newSuspendedState = true;
            // Check voice/data concurrency.
        } else if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()
                && mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
            newSuspendedState = mPhone.getCallTracker().getState() != PhoneConstants.State.IDLE;
        }

        // Only notify when there is a change.
        if (mSuspended != newSuspendedState) {
            mSuspended = newSuspendedState;
            logl("Network becomes " + (mSuspended ? "suspended" : "unsuspended"));
            // To update NOT_SUSPENDED capability.
            updateNetworkCapabilities();
            notifyPreciseDataConnectionState();
            mDataNetworkCallback.invokeFromExecutor(() ->
                    mDataNetworkCallback.onSuspendedStateChanged(DataNetwork.this, mSuspended));
        }
    }

    /**
     * Allocate PDU session ID from the modem. This is only needed when the data network is
     * initiated on IWLAN.
     */
    private void allocatePduSessionId() {
        mRil.allocatePduSessionId(obtainMessage(EVENT_ALLOCATE_PDU_SESSION_ID_RESPONSE));
    }

    /**
     * Setup a data network.
     */
    private void setupData() {
        int dataNetworkType = getDataNetworkType();

        // We need to use the actual modem roaming state instead of the framework roaming state
        // here. This flag is only passed down to ril_service for picking the correct protocol (for
        // old modem backward compatibility).
        boolean isModemRoaming = mPhone.getServiceState().getDataRoamingFromRegistration();

        // Set this flag to true if the user turns on data roaming. Or if we override the roaming
        // state in framework, we should set this flag to true as well so the modem will not reject
        // the data call setup (because the modem actually thinks the device is roaming).
        boolean allowRoaming = mPhone.getDataRoamingEnabled()
                || (isModemRoaming && (!mPhone.getServiceState().getDataRoaming()
                /*|| isUnmeteredUseOnly()*/));

        TrafficDescriptor trafficDescriptor = mDataProfile.getTrafficDescriptor();
        final boolean matchAllRuleAllowed = trafficDescriptor == null
                || !TextUtils.isEmpty(trafficDescriptor.getDataNetworkName());

        int accessNetwork = DataUtils.networkTypeToAccessNetworkType(dataNetworkType);

        mDataServiceManagers.get(mTransport)
                .setupDataCall(accessNetwork, mDataProfile, isModemRoaming, allowRoaming,
                        DataService.REQUEST_REASON_NORMAL, null, mPduSessionId, null,
                        trafficDescriptor, matchAllRuleAllowed,
                        obtainMessage(EVENT_SETUP_DATA_NETWORK_RESPONSE));

        int apnTypeBitmask = mDataProfile.getApnSetting() != null
                ? mDataProfile.getApnSetting().getApnTypeBitmask() : ApnSetting.TYPE_NONE;
        mDataCallSessionStats.onSetupDataCall(apnTypeBitmask);

        logl("setupData: accessNetwork="
                + AccessNetworkType.toString(accessNetwork) + ", " + mDataProfile
                + ", isModemRoaming=" + isModemRoaming + ", allowRoaming=" + allowRoaming
                + ", PDU session id=" + mPduSessionId + ", matchAllRuleAllowed="
                + matchAllRuleAllowed);
        TelephonyMetrics.getInstance().writeSetupDataCall(mPhone.getPhoneId(),
                ServiceState.networkTypeToRilRadioTechnology(dataNetworkType),
                mDataProfile.getProfileId(), mDataProfile.getApn(), mDataProfile.getProtocolType());
    }

    /**
     * Get fail cause from {@link DataCallResponse} and the result code.
     *
     * @param resultCode The result code returned from
     * {@link DataServiceCallback#onSetupDataCallComplete(int, DataCallResponse)}.
     * @param response The data call response returned from
     * {@link DataServiceCallback#onSetupDataCallComplete(int, DataCallResponse)}.
     *
     * @return The fail cause. {@link DataFailCause#NONE} if succeeds.
     */
    private @DataFailureCause int getFailCauseFromDataCallResponse(
            @DataServiceCallback.ResultCode int resultCode, @Nullable DataCallResponse response) {
        int failCause = DataFailCause.NONE;
        switch (resultCode) {
            case DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE:
                failCause = DataFailCause.RADIO_NOT_AVAILABLE;
                break;
            case DataServiceCallback.RESULT_ERROR_BUSY:
            case DataServiceCallback.RESULT_ERROR_TEMPORARILY_UNAVAILABLE:
                failCause = DataFailCause.SERVICE_TEMPORARILY_UNAVAILABLE;
                break;
            case DataServiceCallback.RESULT_ERROR_INVALID_ARG:
                failCause = DataFailCause.UNACCEPTABLE_NETWORK_PARAMETER;
                break;
            case DataServiceCallback.RESULT_ERROR_UNSUPPORTED:
                failCause = DataFailCause.REQUEST_NOT_SUPPORTED;
                break;
            case DataServiceCallback.RESULT_SUCCESS:
                if (response != null) {
                    failCause = DataFailCause.getFailCause(response.getCause());
                }
                break;
        }
        return failCause;
    }

    /**
     * Update data network based on the latest {@link DataCallResponse}.
     *
     * @param response The data call response from data service.
     */
    private void updateDataNetwork(@NonNull DataCallResponse response) {
        mCid.put(mTransport, response.getId());
        LinkProperties linkProperties = new LinkProperties();

        // Set interface name
        linkProperties.setInterfaceName(response.getInterfaceName());

        // Set PDU session id
        if (mPduSessionId != response.getPduSessionId()) {
            mPduSessionId = response.getPduSessionId();
            log("PDU session id updated to " + mPduSessionId);
        }

        // Set the link status
        if (mLinkStatus != response.getLinkStatus()) {
            mLinkStatus = response.getLinkStatus();
            log("Link status updated to " + DataUtils.linkStatusToString(mLinkStatus));
            mDataNetworkCallback.invokeFromExecutor(
                    () -> mDataNetworkCallback.onLinkStatusChanged(DataNetwork.this, mLinkStatus));
        }

        // Set link addresses
        if (response.getAddresses().size() > 0) {
            for (LinkAddress la : response.getAddresses()) {
                if (!la.getAddress().isAnyLocalAddress()) {
                    logv("addr/pl=" + la.getAddress() + "/" + la.getPrefixLength());
                    linkProperties.addLinkAddress(la);
                }
            }
        } else {
            loge("no address for ifname=" + response.getInterfaceName());
        }

        // Set DNS servers
        if (response.getDnsAddresses().size() > 0) {
            for (InetAddress dns : response.getDnsAddresses()) {
                if (!dns.isAnyLocalAddress()) {
                    linkProperties.addDnsServer(dns);
                }
            }
        } else {
            loge("Empty dns response");
        }

        // Set PCSCF
        if (response.getPcscfAddresses().size() > 0) {
            for (InetAddress pcscf : response.getPcscfAddresses()) {
                linkProperties.addPcscfServer(pcscf);
            }
        }

        // For backwards compatibility, use getMtu() if getMtuV4() is not available.
        int mtuV4 = response.getMtuV4() > 0 ? response.getMtuV4() : response.getMtu();

        if (mtuV4 <= 0) {
            // Use back up value from data profile.
            if (mDataProfile.getApnSetting() != null) {
                mtuV4 = mDataProfile.getApnSetting().getMtuV4();
            }
            if (mtuV4 <= 0) {
                mtuV4 = mDataConfigManager.getDefaultMtu();
            }
        }

        // For backwards compatibility, use getMtu() if getMtuV6() is not available.
        int mtuV6 = response.getMtuV6() > 0 ? response.getMtuV6() : response.getMtu();
        if (mtuV6 <= 0) {
            // Use back up value from data profile.
            if (mDataProfile.getApnSetting() != null) {
                mtuV6 = mDataProfile.getApnSetting().getMtuV6();
            }
            if (mtuV6 <= 0) {
                mtuV6 = mDataConfigManager.getDefaultMtu();
            }
        }

        // Set MTU for each route.
        for (InetAddress gateway : response.getGatewayAddresses()) {
            int mtu = gateway instanceof java.net.Inet6Address ? mtuV6 : mtuV4;
            linkProperties.addRoute(new RouteInfo(null, gateway, null,
                    RouteInfo.RTN_UNICAST, mtu));
        }

        // LinkProperties.setMtu should be deprecated. The mtu for each route has been already
        // provided in addRoute() above. For backwards compatibility, we still need to provide
        // a value for the legacy MTU. Use the higher value of v4 and v6 value here.
        linkProperties.setMtu(Math.max(mtuV4, mtuV6));

        if (mDataProfile.getApnSetting() != null
                && !TextUtils.isEmpty(mDataProfile.getApnSetting().getProxyAddressAsString())) {
            int port = mDataProfile.getApnSetting().getProxyPort();
            if (port == -1) {
                port = 8080;
            }
            ProxyInfo proxy = ProxyInfo.buildDirectProxy(
                    mDataProfile.getApnSetting().getProxyAddressAsString(), port);
            linkProperties.setHttpProxy(proxy);
        }

        linkProperties.setTcpBufferSizes(mTcpBufferSizes);

        mNetworkSliceInfo = response.getSliceInfo();

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

        mQosBearerSessions.clear();
        mQosBearerSessions.addAll(response.getQosBearerSessions());
        if (mQosCallbackTracker != null) {
            mQosCallbackTracker.updateSessions(mQosBearerSessions);
        }

        if (!linkProperties.equals(mLinkProperties)) {
            // If the new link properties is not compatible (e.g. IP changes, interface changes),
            // then we should de-register the network agent and re-create a new one.
            if ((isConnected() || isHandoverInProgress())
                    && !isLinkPropertiesCompatible(linkProperties, mLinkProperties)) {
                logl("updateDataNetwork: Incompatible link properties detected. Re-create the "
                        + "network agent. Changed from " + mLinkProperties + " to "
                        + linkProperties);

                mLinkProperties = linkProperties;

                // Abandon the network agent because we are going to create a new one.
                mNetworkAgent.abandon();
                // Update the link properties first so the new network agent would be created with
                // the new link properties.
                mLinkProperties = linkProperties;
                mNetworkAgent = createNetworkAgent();
                mNetworkAgent.markConnected();
            } else {
                mLinkProperties = linkProperties;
                log("sendLinkProperties " + mLinkProperties);
                mNetworkAgent.sendLinkProperties(mLinkProperties);
            }
        }

        updateNetworkCapabilities();
    }

    /**
     * Called when receiving setup data network response from the data service.
     *
     * @param resultCode The result code.
     * @param response The response.
     */
    private void onSetupResponse(@DataServiceCallback.ResultCode int resultCode,
            @Nullable DataCallResponse response) {
        logl("onSetupResponse: resultCode=" + DataServiceCallback.resultCodeToString(resultCode)
                + ", response=" + response);
        mFailCause = getFailCauseFromDataCallResponse(resultCode, response);
        validateDataCallResponse(response);
        if (mFailCause == DataFailCause.NONE) {
            if (mDataNetworkController.isNetworkInterfaceExisting(response.getInterfaceName())) {
                logl("Interface " + response.getInterfaceName() + " already existing. Silently "
                        + "tear down now.");
                // If this is a pre-5G data setup, that means APN database has some problems. For
                // example, different APN settings have the same APN name.
                if (response.getTrafficDescriptors().isEmpty()) {
                    reportAnomaly("Duplicate network interface " + response.getInterfaceName()
                            + " detected.", "62f66e7e-8d71-45de-a57b-dc5c78223fd5");
                }

                // Do not actually invoke onTearDown, otherwise the existing data network will be
                // torn down.
                mRetryDelayMillis = DataCallResponse.RETRY_DURATION_UNDEFINED;
                mFailCause = DataFailCause.NO_RETRY_FAILURE;
                transitionTo(mDisconnectedState);
                return;
            }

            updateDataNetwork(response);

            // TODO: Evaluate all network requests and see if each request still can be satisfied.
            //  For requests that can't be satisfied anymore, we need to put them back to the
            //  unsatisfied pool. If none of network requests can be satisfied, then there is no
            //  need to mark network agent connected. Just silently deactivate the data network.
            if (mAttachedNetworkRequestList.size() == 0) {
                log("Tear down the network since there is no live network request.");
                // Directly call onTearDown here. Calling tearDown will cause deadlock because
                // EVENT_TEAR_DOWN_NETWORK is deferred until state machine enters connected state,
                // which will never happen in this case.
                onTearDown(TEAR_DOWN_REASON_NO_LIVE_REQUEST);
                return;
            }

            if (mVcnManager != null && mVcnManager.applyVcnNetworkPolicy(mNetworkCapabilities,
                    mLinkProperties).isTeardownRequested()) {
                log("VCN service requested to tear down the network.");
                // Directly call onTearDown here. Calling tearDown will cause deadlock because
                // EVENT_TEAR_DOWN_NETWORK is deferred until state machine enters connected state,
                // which will never happen in this case.
                onTearDown(TEAR_DOWN_REASON_VCN_REQUESTED);
                return;
            }

            transitionTo(mConnectedState);
        } else {
            // Setup data failed.
            mRetryDelayMillis = response != null ? response.getRetryDurationMillis()
                    : DataCallResponse.RETRY_DURATION_UNDEFINED;
            transitionTo(mDisconnectedState);
        }

        int apnTypeBitmask = ApnSetting.TYPE_NONE;
        int protocol = ApnSetting.PROTOCOL_UNKNOWN;
        if (mDataProfile.getApnSetting() != null) {
            apnTypeBitmask = mDataProfile.getApnSetting().getApnTypeBitmask();
            protocol = mDataProfile.getApnSetting().getProtocol();
        }
        mDataCallSessionStats.onSetupDataCallResponse(response,
                getDataNetworkType(),
                apnTypeBitmask,
                protocol,
                mFailCause);
    }

    /**
     * If the {@link DataCallResponse} contains invalid info, triggers an anomaly report.
     *
     * @param response The response to be validated
     */
    private void validateDataCallResponse(@Nullable DataCallResponse response) {
        if (response == null
                || response.getLinkStatus() == DataCallResponse.LINK_STATUS_INACTIVE) return;
        int failCause = response.getCause();
        if (failCause == DataFailCause.NONE) {
            if (TextUtils.isEmpty(response.getInterfaceName())
                    || response.getAddresses().isEmpty()
                    // if out of range
                    || response.getLinkStatus() < DataCallResponse.LINK_STATUS_UNKNOWN
                    || response.getLinkStatus() > DataCallResponse.LINK_STATUS_ACTIVE
                    || response.getProtocolType() < ApnSetting.PROTOCOL_UNKNOWN
                    || response.getProtocolType() > ApnSetting.PROTOCOL_UNSTRUCTURED
                    || response.getHandoverFailureMode()
                    < DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN
                    || response.getHandoverFailureMode()
                    > DataCallResponse.HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL) {
                loge("Invalid DataCallResponse:" + response);
                reportAnomaly("Invalid DataCallResponse detected",
                        "1f273e9d-b09c-46eb-ad1c-421d01f61164");
            }
        } else if (!DataFailCause.isFailCauseExisting(failCause)) { // Setup data failed.
            loge("Invalid DataFailCause in " + response);
            reportAnomaly("Invalid DataFailCause: (0x" + Integer.toHexString(failCause)
                            + ")",
                    "6b264f28-9f58-4cbd-9e0e-d7624ba30879");
        }
    }

    /**
     * Called when receiving deactivate data network response from the data service.
     *
     * @param resultCode The result code.
     */
    private void onDeactivateResponse(@DataServiceCallback.ResultCode int resultCode) {
        logl("onDeactivateResponse: resultCode="
                + DataServiceCallback.resultCodeToString(resultCode));
        if (resultCode == DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE) {
            log("Remove network since deactivate request returned an error.");
            mFailCause = DataFailCause.RADIO_NOT_AVAILABLE;
            transitionTo(mDisconnectedState);
        } else if (mPhone.getHalVersion().less(RIL.RADIO_HAL_VERSION_2_0)) {
            log("Remove network on deactivate data response on old HAL "
                    + mPhone.getHalVersion());
            mFailCause = DataFailCause.LOST_CONNECTION;
            transitionTo(mDisconnectedState);
        }
    }

    /**
     * Tear down the data network immediately.
     *
     * @param reason The reason of tearing down the network.
     */
    public void tearDown(@TearDownReason int reason) {
        if (getCurrentState() == null || isDisconnected()) {
            return;
        }
        sendMessage(obtainMessage(EVENT_TEAR_DOWN_NETWORK, reason));
    }

    private void onTearDown(@TearDownReason int reason) {
        logl("onTearDown: reason=" + tearDownReasonToString(reason));

        // track frequent NetworkAgent.onNetworkUnwanted() call of IMS and INTERNET
        if (reason == TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED
                && isConnected()
                && (mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
                || mNetworkCapabilities.hasCapability(
                        NetworkCapabilities.NET_CAPABILITY_INTERNET))) {
            mDataNetworkCallback.onTrackNetworkUnwanted(this);
        }

        mDataServiceManagers.get(mTransport).deactivateDataCall(mCid.get(mTransport),
                reason == TEAR_DOWN_REASON_AIRPLANE_MODE_ON ? DataService.REQUEST_REASON_SHUTDOWN
                        : DataService.REQUEST_REASON_NORMAL,
                obtainMessage(EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE));
        mDataCallSessionStats.setDeactivateDataCallReason(DataService.REQUEST_REASON_NORMAL);
        mInvokedDataDeactivation = true;
    }

    /**
     * @return {@code true} if this is an IMS network and tear down should be delayed until call
     * ends on this data network.
     */
    public boolean shouldDelayImsTearDown() {
        return mDataConfigManager.isImsDelayTearDownEnabled()
                && mNetworkCapabilities != null
                && mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL)
                && mPhone.getImsPhone() != null
                && mPhone.getImsPhone().getCallTracker().getState()
                != PhoneConstants.State.IDLE;
    }

    /**
     * Tear down the data network when condition is met or timed out. Data network will enter
     * {@link DisconnectingState} immediately and waiting for condition met. When condition is met,
     * {@link DataNetworkController} should invoke {@link Consumer#accept(Object)} so the actual
     * tear down work can be performed.
     *
     * This is primarily used for IMS graceful tear down. {@link DataNetworkController} inform
     * {@link DataNetwork} to enter {@link DisconnectingState}. IMS service can observe this
     * through {@link PreciseDataConnectionState#getState()} and then perform IMS de-registration
     * work. After IMS de-registered, {@link DataNetworkController} informs {@link DataNetwork}
     * that it's okay to tear down the network.
     *
     * @param reason The tear down reason.
     *
     * @param timeoutMillis Timeout in milliseconds. Within the time window, clients will have to
     * call {@link Consumer#accept(Object)}, otherwise, data network will be torn down when
     * timed out.
     *
     * @return The runnable for client to execute when condition is met. When executed, tear down
     * will be performed. {@code null} if the data network is already disconnected or being
     * disconnected.
     */
    public @Nullable Runnable tearDownWhenConditionMet(@TearDownReason int reason,
            long timeoutMillis) {
        if (getCurrentState() == null || isDisconnected() || isDisconnecting()) {
            loge("tearDownWhenConditionMet: Not in the right state. State=" + getCurrentState());
            return null;
        }
        logl("tearDownWhenConditionMet: reason=" + tearDownReasonToString(reason) + ", timeout="
                + timeoutMillis + "ms.");
        sendMessage(EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET, reason, (int) timeoutMillis);
        return () -> this.tearDown(reason);
    }

    /**
     * Called when receiving {@link DataServiceCallback#onDataCallListChanged(List)} from the data
     * service.
     *
     * @param transport The transport where this event from.
     * @param responseList The data call response list.
     */
    private void onDataStateChanged(@TransportType int transport,
            @NonNull List<DataCallResponse> responseList) {
        // Ignore the update if it's not from the data service on the right transport.
        // Also if never received data call response from setup call response, which updates the
        // cid, ignore the update here.
        logv("onDataStateChanged: " + responseList);
        if (transport != mTransport || mCid.get(mTransport) == INVALID_CID || isDisconnected()) {
            return;
        }

        DataCallResponse response = responseList.stream()
                .filter(r -> mCid.get(mTransport) == r.getId())
                .findFirst()
                .orElse(null);
        if (response != null) {
            if (!response.equals(mDataCallResponse)) {
                log("onDataStateChanged: " + response);
                validateDataCallResponse(response);
                mDataCallResponse = response;
                if (response.getLinkStatus() != DataCallResponse.LINK_STATUS_INACTIVE) {
                    updateDataNetwork(response);
                } else {
                    log("onDataStateChanged: PDN inactive reported by "
                            + AccessNetworkConstants.transportTypeToString(mTransport)
                            + " data service.");
                    mFailCause = mEverConnected ? response.getCause()
                            : DataFailCause.NO_RETRY_FAILURE;
                    mRetryDelayMillis = DataCallResponse.RETRY_DURATION_UNDEFINED;
                    transitionTo(mDisconnectedState);
                }
            }
        } else {
            // The data call response is missing from the list. This means the PDN is gone. This
            // is the PDN lost reported by the modem. We don't send another DEACTIVATE_DATA request
            // for that
            log("onDataStateChanged: PDN disconnected reported by "
                    + AccessNetworkConstants.transportTypeToString(mTransport) + " data service.");
            mFailCause = mEverConnected ? DataFailCause.LOST_CONNECTION
                    : DataFailCause.NO_RETRY_FAILURE;
            mRetryDelayMillis = DataCallResponse.RETRY_DURATION_UNDEFINED;
            transitionTo(mDisconnectedState);
        }
    }

    /**
     * Called when data config updated.
     */
    private void onDataConfigUpdated() {
        log("onDataConfigUpdated");

        updateBandwidthFromDataConfig();
        updateTcpBufferSizes();
        updateMeteredAndCongested();
    }

    /**
     * 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);
        NetworkBandwidth bandwidthFromConfig = mDataConfigManager.getBandwidthForNetworkType(
                mTelephonyDisplayInfo);

        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 {@link TelephonyDisplayInfo} changed. This can happen when network types or
     * override network types (5G NSA, 5G MMWAVE) change.
     */
    private void onDisplayInfoChanged() {
        mTelephonyDisplayInfo = mPhone.getDisplayInfoController().getTelephonyDisplayInfo();
        updateBandwidthFromDataConfig();
        updateTcpBufferSizes();
        updateMeteredAndCongested();
    }

    /**
     * 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");
        mNetworkBandwidth = mDataConfigManager.getBandwidthForNetworkType(mTelephonyDisplayInfo);
        updateNetworkCapabilities();
    }

    /**
     * Update the TCP buffer sizes from resource overlays.
     */
    private void updateTcpBufferSizes() {
        log("updateTcpBufferSizes");
        mTcpBufferSizes = mDataConfigManager.getTcpConfigString(mTelephonyDisplayInfo);
        LinkProperties linkProperties = new LinkProperties(mLinkProperties);
        linkProperties.setTcpBufferSizes(mTcpBufferSizes);
        if (!linkProperties.equals(mLinkProperties)) {
            mLinkProperties = linkProperties;
            log("sendLinkProperties " + mLinkProperties);
            mNetworkAgent.sendLinkProperties(mLinkProperties);
        }
    }

    /**
     * Update the metered and congested values from carrier configs and subscription overrides
     */
    private void updateMeteredAndCongested() {
        int networkType = mTelephonyDisplayInfo.getNetworkType();
        switch (mTelephonyDisplayInfo.getOverrideNetworkType()) {
            case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED:
            case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA:
                networkType = TelephonyManager.NETWORK_TYPE_NR;
                break;
            case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO:
            case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA:
                networkType = TelephonyManager.NETWORK_TYPE_LTE_CA;
                break;
        }
        log("updateMeteredAndCongested: networkType="
                + TelephonyManager.getNetworkTypeName(networkType));
        boolean changed = false;
        if (mDataConfigManager.isTempNotMeteredSupportedByCarrier() != mTempNotMeteredSupported) {
            mTempNotMeteredSupported = !mTempNotMeteredSupported;
            changed = true;
            log("updateMeteredAndCongested: mTempNotMeteredSupported changed to "
                    + mTempNotMeteredSupported);
        }
        if ((mDataNetworkController.getUnmeteredOverrideNetworkTypes().contains(networkType)
                || isNetworkTypeUnmetered(networkType)) != mTempNotMetered) {
            mTempNotMetered = !mTempNotMetered;
            changed = true;
            log("updateMeteredAndCongested: mTempNotMetered changed to " + mTempNotMetered);
        }
        if (mDataNetworkController.getCongestedOverrideNetworkTypes().contains(networkType)
                != mCongested) {
            mCongested = !mCongested;
            changed = true;
            log("updateMeteredAndCongested: mCongested changed to " + mCongested);
        }
        if (changed) {
            updateNetworkCapabilities();
        }
    }

    /**
     * Get whether the network type is unmetered from SubscriptionPlans, from either an unmetered
     * general plan or specific plan for the given network type.
     *
     * @param networkType The network type to check meteredness for
     * @return Whether the given network type is unmetered based on SubscriptionPlans
     */
    private boolean isNetworkTypeUnmetered(@NetworkType int networkType) {
        List<SubscriptionPlan> plans = mDataNetworkController.getSubscriptionPlans();
        if (plans.isEmpty()) return false;
        boolean isGeneralUnmetered = true;
        Set<Integer> allNetworkTypes = Arrays.stream(TelephonyManager.getAllNetworkTypes())
                .boxed().collect(Collectors.toSet());
        for (SubscriptionPlan plan : plans) {
            // Check if plan is general (applies to all network types) or specific
            if (Arrays.stream(plan.getNetworkTypes()).boxed().collect(Collectors.toSet())
                    .containsAll(allNetworkTypes)) {
                if (plan.getDataLimitBytes() != SubscriptionPlan.BYTES_UNLIMITED) {
                    // Metered takes precedence over unmetered for safety
                    isGeneralUnmetered = false;
                }
            } else {
                // Check if plan applies to given network type
                if (networkType != TelephonyManager.NETWORK_TYPE_UNKNOWN) {
                    for (int planNetworkType : plan.getNetworkTypes()) {
                        if (planNetworkType == networkType) {
                            return plan.getDataLimitBytes() == SubscriptionPlan.BYTES_UNLIMITED;
                        }
                    }
                }
            }
        }
        return isGeneralUnmetered;
    }

    /**
     * @return The unique context id assigned by the data service in
     * {@link DataCallResponse#getId()}.
     */
    public int getId() {
        return mCid.get(mTransport);
    }

    /**
     * @return The current network type reported by the network service.
     */
    private @NetworkType int getDataNetworkType() {
        return getDataNetworkType(mTransport);
    }

    /**
     * Get the data network type on the specified transport.
     *
     * @param transport The transport.
     * @return The data network type.
     */
    private @NetworkType int getDataNetworkType(@TransportType int transport) {
        // WLAN transport can't have network type other than IWLAN. Ideally service state tracker
        // should report the correct RAT, but sometimes race condition could happen that service
        // state is reset to out of service and RAT not updated to IWLAN yet.
        if (transport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
            return TelephonyManager.NETWORK_TYPE_IWLAN;
        }

        ServiceState ss = mPhone.getServiceState();
        NetworkRegistrationInfo nrs = ss.getNetworkRegistrationInfo(
                NetworkRegistrationInfo.DOMAIN_PS, transport);
        if (nrs != null) {
            return nrs.getAccessNetworkTechnology();
        }
        return TelephonyManager.NETWORK_TYPE_UNKNOWN;
    }

    /**
     * @return The physical link status (i.e. RRC state).
     */
    public @LinkStatus int getLinkStatus() {
        return mLinkStatus;
    }

    /**
     * Update the network score and report to connectivity service if necessary.
     */
    private void updateNetworkScore() {
        int networkScore = getNetworkScore();
        if (networkScore != mNetworkScore) {
            logl("Updating score from " + mNetworkScore + " to " + networkScore);
            mNetworkScore = networkScore;
            mNetworkAgent.sendNetworkScore(mNetworkScore);
        }
    }

    /**
     * @return The network score. The higher score of the network has higher chance to be
     * selected by the connectivity service as active network.
     */
    private int getNetworkScore() {
        // If it's serving a network request that asks NET_CAPABILITY_INTERNET and doesn't have
        // specify a sub id, this data network is considered to be default internet data
        // connection. In this case we assign a slightly higher score of 50. The intention is
        // it will not be replaced by other data networks accidentally in DSDS use case.
        int score = OTHER_NETWORK_SCORE;
        for (TelephonyNetworkRequest networkRequest : mAttachedNetworkRequestList) {
            if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                    && networkRequest.getNetworkSpecifier() == null) {
                score = DEFAULT_INTERNET_NETWORK_SCORE;
            }
        }

        return score;
    }

    /**
     * @return Network registration info on the current transport.
     */
    private @Nullable NetworkRegistrationInfo getNetworkRegistrationInfo() {
        NetworkRegistrationInfo nri = mPhone.getServiceStateTracker().getServiceState()
                .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS, mTransport);
        if (nri == null) {
            loge("Can't get network registration info for "
                    + AccessNetworkConstants.transportTypeToString(mTransport));
            return null;
        }
        return nri;
    }

    /**
     * Get the APN type network capability. If there are more than one capabilities that are
     * APN types, then return the highest priority one which also has associated network request.
     * For example, if the network supports both MMS and internet, but only internet request
     * attached at this time, then the capability would be internet. Later on if MMS network request
     * attached to this network, then the APN type capability would be MMS.
     *
     * @return The APN type network capability from this network.
     *
     * @see #getPriority()
     */
    public @NetCapability int getApnTypeNetworkCapability() {
        if (!mAttachedNetworkRequestList.isEmpty()) {
            // The highest priority network request is always at the top of list.
            return mAttachedNetworkRequestList.get(0).getApnTypeNetworkCapability();
        } else {
            return Arrays.stream(getNetworkCapabilities().getCapabilities()).boxed()
                    .filter(cap -> DataUtils.networkCapabilityToApnType(cap)
                            != ApnSetting.TYPE_NONE)
                    .max(Comparator.comparingInt(mDataConfigManager::getNetworkCapabilityPriority))
                    .orElse(-1);
        }
    }

    /**
     * Get the priority of the network. The priority is derived from the highest priority capability
     * which also has such associated network request. For example, if the network supports both
     * MMS and internet, but only has internet request attached, then this network has internet's
     * priority. Later on when the MMS request attached to this network, the network's priority will
     * be updated to MMS's priority.
     *
     * @return The priority of the network.
     *
     * @see #getApnTypeNetworkCapability()
     */
    public int getPriority() {
        if (!mAttachedNetworkRequestList.isEmpty()) {
            // The highest priority network request is always at the top of list.
            return mAttachedNetworkRequestList.get(0).getPriority();
        } else {
            // If all network requests are already detached, then just pick the highest priority
            // capability's priority.
            return Arrays.stream(getNetworkCapabilities().getCapabilities()).boxed()
                    .map(mDataConfigManager::getNetworkCapabilityPriority)
                    .max(Integer::compare)
                    .orElse(0);
        }
    }

    /**
     * @return The attached network request list.
     */
    public @NonNull NetworkRequestList getAttachedNetworkRequestList() {
        return mAttachedNetworkRequestList;
    }

    /**
     * @return {@code true} if in connecting state.
     */
    public boolean isConnecting() {
        return getCurrentState() == mConnectingState;
    }

    /**
     * @return {@code true} if in connected state.
     */
    public boolean isConnected() {
        return getCurrentState() == mConnectedState;
    }

    /**
     * @return {@code true} if in disconnecting state.
     */
    public boolean isDisconnecting() {
        return getCurrentState() == mDisconnectingState;
    }

    /**
     * @return {@code true} if in disconnected state.
     */
    public boolean isDisconnected() {
        return getCurrentState() == mDisconnectedState;
    }

    /**
     * @return {@code true} if in handover state.
     */
    public boolean isHandoverInProgress() {
        return getCurrentState() == mHandoverState;
    }

    /**
     * @return {@code true} if the data network is suspended.
     */
    public boolean isSuspended() {
        return getState() == TelephonyManager.DATA_SUSPENDED;
    }

    /**
     * @return The current transport of the data network.
     */
    public @TransportType int getTransport() {
        return mTransport;
    }

    private @DataState int getState() {
        IState state = getCurrentState();
        if (state == null || isDisconnected()) {
            return TelephonyManager.DATA_DISCONNECTED;
        } else if (isConnecting()) {
            return TelephonyManager.DATA_CONNECTING;
        } else if (isConnected()) {
            // The data connection can only be suspended when it's in active state.
            if (mSuspended) {
                return TelephonyManager.DATA_SUSPENDED;
            }
            return TelephonyManager.DATA_CONNECTED;
        } else if (isDisconnecting()) {
            return TelephonyManager.DATA_DISCONNECTING;
        } else if (isHandoverInProgress()) {
            return TelephonyManager.DATA_HANDOVER_IN_PROGRESS;
        }

        return TelephonyManager.DATA_UNKNOWN;
    }

    /**
     * @return {@code true} if this data network supports internet.
     */
    public boolean isInternetSupported() {
        return mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                && mNetworkCapabilities.hasCapability(
                        NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
                && mNetworkCapabilities.hasCapability(
                        NetworkCapabilities.NET_CAPABILITY_TRUSTED)
                && mNetworkCapabilities.hasCapability(
                        NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
                && mNetworkCapabilities.hasCapability(
                        NetworkCapabilities.NET_CAPABILITY_NOT_VPN);
    }

    /**
     * @return {@code true} if this network was setup for SUPL during emergency call. {@code false}
     * otherwise.
     */
    public boolean isEmergencySupl() {
        return mDataAllowedReason == DataAllowedReason.EMERGENCY_SUPL;
    }

    /**
     * Get precise data connection state
     *
     * @return The {@link PreciseDataConnectionState}
     */
    private PreciseDataConnectionState getPreciseDataConnectionState() {
        return new PreciseDataConnectionState.Builder()
                .setTransportType(mTransport)
                .setId(mCid.get(mTransport))
                .setState(getState())
                .setApnSetting(mDataProfile.getApnSetting())
                .setLinkProperties(mLinkProperties)
                .setNetworkType(getDataNetworkType())
                .setFailCause(mFailCause)
                .build();
    }

    /**
     * Send the precise data connection state to the listener of
     * {@link android.telephony.TelephonyCallback.PreciseDataConnectionStateListener}.
     */
    private void notifyPreciseDataConnectionState() {
        PreciseDataConnectionState pdcs = getPreciseDataConnectionState();
        logv("notifyPreciseDataConnectionState=" + pdcs);
        mPhone.notifyDataConnection(pdcs);
    }

    /**
     * Request the data network to handover to the target transport.
     *
     * @param targetTransport The target transport.
     * @param retryEntry Data handover retry entry. This would be {@code null} for first time
     * handover attempt.
     * @return {@code true} if the request has been accepted.
     */
    public boolean startHandover(@TransportType int targetTransport,
            @Nullable DataHandoverRetryEntry retryEntry) {
        if (getCurrentState() == null || isDisconnected() || isDisconnecting()) {
            // Fail the request if not in the appropriate state.
            if (retryEntry != null) retryEntry.setState(DataRetryEntry.RETRY_STATE_CANCELLED);
            return false;
        }
        sendMessage(obtainMessage(EVENT_START_HANDOVER, targetTransport, 0, retryEntry));
        return true;
    }

    /**
     * Called when handover between IWLAN and cellular is needed.
     *
     * @param targetTransport The target transport.
     * @param retryEntry Data handover retry entry. This would be {@code null} for first time
     * handover attempt.
     */
    private void onStartHandover(@TransportType int targetTransport,
            @Nullable DataHandoverRetryEntry retryEntry) {
        if (mTransport == targetTransport) {
            log("onStartHandover: The network is already on "
                    + AccessNetworkConstants.transportTypeToString(mTransport)
                    + ", handover is not needed.");
            if (retryEntry != null) retryEntry.setState(DataRetryEntry.RETRY_STATE_CANCELLED);
            return;
        }

        // We need to use the actual modem roaming state instead of the framework roaming state
        // here. This flag is only passed down to ril_service for picking the correct protocol (for
        // old modem backward compatibility).
        boolean isModemRoaming = mPhone.getServiceState().getDataRoamingFromRegistration();

        // Set this flag to true if the user turns on data roaming. Or if we override the roaming
        // state in framework, we should set this flag to true as well so the modem will not reject
        // the data call setup (because the modem actually thinks the device is roaming).
        boolean allowRoaming = mPhone.getDataRoamingEnabled()
                || (isModemRoaming && (!mPhone.getServiceState().getDataRoaming()));

        mHandoverDataProfile = mDataProfile;
        int targetNetworkType = getDataNetworkType(targetTransport);
        if (targetNetworkType != TelephonyManager.NETWORK_TYPE_UNKNOWN
                && !mAttachedNetworkRequestList.isEmpty()) {
            TelephonyNetworkRequest networkRequest = mAttachedNetworkRequestList.get(0);
            DataProfile dataProfile = mDataNetworkController.getDataProfileManager()
                    .getDataProfileForNetworkRequest(networkRequest, targetNetworkType);
            // Some carriers have different profiles between cellular and IWLAN. We need to
            // dynamically switch profile, but only when those profiles have same APN name.
            if (dataProfile != null && dataProfile.getApnSetting() != null
                    && mDataProfile.getApnSetting() != null
                    && TextUtils.equals(dataProfile.getApnSetting().getApnName(),
                    mDataProfile.getApnSetting().getApnName())
                    && !dataProfile.equals(mDataProfile)) {
                mHandoverDataProfile = dataProfile;
                log("Used different data profile for handover. " + mDataProfile);
            }
        }

        logl("Start handover from " + AccessNetworkConstants.transportTypeToString(mTransport)
                + " to " + AccessNetworkConstants.transportTypeToString(targetTransport));
        // Send the handover request to the target transport data service.
        mDataServiceManagers.get(targetTransport).setupDataCall(
                DataUtils.networkTypeToAccessNetworkType(getDataNetworkType(targetTransport)),
                mHandoverDataProfile, isModemRoaming, allowRoaming,
                DataService.REQUEST_REASON_HANDOVER, mLinkProperties, mPduSessionId,
                mNetworkSliceInfo, mHandoverDataProfile.getTrafficDescriptor(), true,
                obtainMessage(EVENT_HANDOVER_RESPONSE, retryEntry));
        transitionTo(mHandoverState);
    }

    /**
     * Called when receiving handover response from the data service.
     *
     * @param resultCode The result code.
     * @param response The response.
     * @param retryEntry Data handover retry entry. This would be {@code null} for first time
     * handover attempt.
     */
    private void onHandoverResponse(@DataServiceCallback.ResultCode int resultCode,
            @Nullable DataCallResponse response, @Nullable DataHandoverRetryEntry retryEntry) {
        logl("onHandoverResponse: resultCode=" + DataServiceCallback.resultCodeToString(resultCode)
                + ", response=" + response);
        mFailCause = getFailCauseFromDataCallResponse(resultCode, response);
        validateDataCallResponse(response);
        if (mFailCause == DataFailCause.NONE) {
            // Handover succeeded.

            // Clean up on the source transport.
            mDataServiceManagers.get(mTransport).deactivateDataCall(mCid.get(mTransport),
                    DataService.REQUEST_REASON_HANDOVER, null);
            // Switch the transport to the target.
            mTransport = DataUtils.getTargetTransport(mTransport);
            // Update the logging tag
            mLogTag = "DN-" + mInitialNetworkAgentId + "-"
                    + ((mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) ? "C" : "I");
            // Switch the data profile. This is no-op in most of the case since almost all carriers
            // use same data profile between IWLAN and cellular.
            mDataProfile = mHandoverDataProfile;
            updateDataNetwork(response);
            if (mTransport != AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
                unregisterForWwanEvents();
            } else {
                // Handover from WLAN to WWAN
                registerForWwanEvents();
            }
            if (retryEntry != null) retryEntry.setState(DataRetryEntry.RETRY_STATE_SUCCEEDED);
            mDataNetworkCallback.invokeFromExecutor(
                    () -> mDataNetworkCallback.onHandoverSucceeded(DataNetwork.this));
        } else {
            // Handover failed.
            long retry = response != null ? response.getRetryDurationMillis()
                    : DataCallResponse.RETRY_DURATION_UNDEFINED;
            int handoverFailureMode = response != null ? response.getHandoverFailureMode()
                    : DataCallResponse.HANDOVER_FAILURE_MODE_LEGACY;
            if (retryEntry != null) retryEntry.setState(DataRetryEntry.RETRY_STATE_FAILED);
            mDataNetworkCallback.invokeFromExecutor(
                    () -> mDataNetworkCallback.onHandoverFailed(DataNetwork.this,
                            mFailCause, retry, handoverFailureMode));
            mDataCallSessionStats.onHandoverFailure(mFailCause);
        }

        // No matter handover succeeded or not, transit back to connected state.
        transitionTo(mConnectedState);
    }

    /**
     * Called when PCO data changes.
     *
     * @param pcoData The PCO data.
     */
    private void onPcoDataChanged(@NonNull PcoData pcoData) {
        log("onPcoDataChanged: " + pcoData);
        mDataNetworkCallback.invokeFromExecutor(
                () -> mDataNetworkCallback.onPcoDataChanged(DataNetwork.this));
        if (mDataProfile.getApnSetting() != null) {
            for (int apnType : mDataProfile.getApnSetting().getApnTypes()) {
                Intent intent = new Intent(TelephonyManager.ACTION_CARRIER_SIGNAL_PCO_VALUE);
                intent.putExtra(TelephonyManager.EXTRA_APN_TYPE, apnType);
                intent.putExtra(TelephonyManager.EXTRA_APN_PROTOCOL,
                        ApnSetting.getProtocolIntFromString(pcoData.bearerProto));
                intent.putExtra(TelephonyManager.EXTRA_PCO_ID, pcoData.pcoId);
                intent.putExtra(TelephonyManager.EXTRA_PCO_VALUE, pcoData.contents);
                mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
            }
        }
    }

    /**
     * Called when receiving PCO (Protocol Configuration Options) data from the cellular network.
     *
     * @param pcoData PCO data.
     */
    private void onPcoDataReceived(@NonNull PcoData pcoData) {
        // Save all the PCO data received, even though it might be unrelated to this data network.
        // The network might be still in connecting state. Save all now and use it when entering
        // connected state.
        log("onPcoDataReceived: " + pcoData);
        PcoData oldData = mPcoData.computeIfAbsent(pcoData.cid, m -> new ArrayMap<>())
                .put(pcoData.pcoId, pcoData);
        if (getId() == INVALID_CID || pcoData.cid != getId()) return;
        if (!Objects.equals(oldData, pcoData)) {
            onPcoDataChanged(pcoData);
        }
    }

    /**
     * @return The PCO data map of the network. The key is the PCO id, the value is the PCO data.
     * An empty map if PCO data is not available.
     */
    public @NonNull Map<Integer, PcoData> getPcoData() {
        if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN
                || mCid.get(mTransport) == INVALID_CID) {
            return Collections.emptyMap();
        }
        return mPcoData.get(mCid.get(mTransport));
    }

    /**
     * Check if the this data network is VCN-managed.
     *
     * @param networkCapabilities The network capabilities of this data network.
     * @return The VCN's policy for this DataNetwork.
     */
    private VcnNetworkPolicyResult getVcnPolicy(NetworkCapabilities networkCapabilities) {
        if (mVcnManager == null) {
            return null;
        }

        return mVcnManager.applyVcnNetworkPolicy(networkCapabilities, getLinkProperties());
    }

    /**
     * Convert the data tear down reason to string.
     *
     * @param reason Data deactivation reason.
     * @return The deactivation reason in string format.
     */
    public static @NonNull String tearDownReasonToString(@TearDownReason int reason) {
        switch (reason) {
            case TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED:
                return "CONNECTIVITY_SERVICE_UNWANTED";
            case TEAR_DOWN_REASON_SIM_REMOVAL:
                return "SIM_REMOVAL";
            case TEAR_DOWN_REASON_AIRPLANE_MODE_ON:
                return "AIRPLANE_MODE_ON";
            case TEAR_DOWN_REASON_DATA_DISABLED:
                return "DATA_DISABLED";
            case TEAR_DOWN_REASON_NO_LIVE_REQUEST:
                return "TEAR_DOWN_REASON_NO_LIVE_REQUEST";
            case TEAR_DOWN_REASON_RAT_NOT_ALLOWED:
                return "TEAR_DOWN_REASON_RAT_NOT_ALLOWED";
            case TEAR_DOWN_REASON_ROAMING_DISABLED:
                return "TEAR_DOWN_REASON_ROAMING_DISABLED";
            case TEAR_DOWN_REASON_CONCURRENT_VOICE_DATA_NOT_ALLOWED:
                return "TEAR_DOWN_REASON_CONCURRENT_VOICE_DATA_NOT_ALLOWED";
            case TEAR_DOWN_REASON_DATA_SERVICE_NOT_READY:
                return "TEAR_DOWN_REASON_DATA_SERVICE_NOT_READY";
            case TEAR_DOWN_REASON_POWER_OFF_BY_CARRIER:
                return "TEAR_DOWN_REASON_POWER_OFF_BY_CARRIER";
            case TEAR_DOWN_REASON_DATA_STALL:
                return "TEAR_DOWN_REASON_DATA_STALL";
            case TEAR_DOWN_REASON_HANDOVER_FAILED:
                return "TEAR_DOWN_REASON_HANDOVER_FAILED";
            case TEAR_DOWN_REASON_HANDOVER_NOT_ALLOWED:
                return "TEAR_DOWN_REASON_HANDOVER_NOT_ALLOWED";
            case TEAR_DOWN_REASON_VCN_REQUESTED:
                return "TEAR_DOWN_REASON_VCN_REQUESTED";
            case TEAR_DOWN_REASON_VOPS_NOT_SUPPORTED:
                return "TEAR_DOWN_REASON_VOPS_NOT_SUPPORTED";
            case TEAR_DOWN_REASON_DEFAULT_DATA_UNSELECTED:
                return "TEAR_DOWN_REASON_DEFAULT_DATA_UNSELECTED";
            case TEAR_DOWN_REASON_NOT_IN_SERVICE:
                return "TEAR_DOWN_REASON_NOT_IN_SERVICE";
            case TEAR_DOWN_REASON_DATA_CONFIG_NOT_READY:
                return "TEAR_DOWN_REASON_DATA_CONFIG_NOT_READY";
            case TEAR_DOWN_REASON_PENDING_TEAR_DOWN_ALL:
                return "TEAR_DOWN_REASON_PENDING_TEAR_DOWN_ALL";
            case TEAR_DOWN_REASON_NO_SUITABLE_DATA_PROFILE:
                return "TEAR_DOWN_REASON_NO_SUITABLE_DATA_PROFILE";
            case TEAR_DOWN_REASON_CDMA_EMERGENCY_CALLBACK_MODE:
                return "TEAR_DOWN_REASON_CDMA_EMERGENCY_CALLBACK_MODE";
            case TEAR_DOWN_REASON_RETRY_SCHEDULED:
                return "TEAR_DOWN_REASON_RETRY_SCHEDULED";
            case TEAR_DOWN_REASON_DATA_THROTTLED:
                return "TEAR_DOWN_REASON_DATA_THROTTLED";
            case TEAR_DOWN_REASON_DATA_PROFILE_INVALID:
                return "TEAR_DOWN_REASON_DATA_PROFILE_INVALID";
            case TEAR_DOWN_REASON_DATA_PROFILE_NOT_PREFERRED:
                return "TEAR_DOWN_REASON_DATA_PROFILE_NOT_PREFERRED";
            case TEAR_DOWN_REASON_NOT_ALLOWED_BY_POLICY:
                return "TEAR_DOWN_REASON_NOT_ALLOWED_BY_POLICY";
            case TEAR_DOWN_REASON_ILLEGAL_STATE:
                return "TEAR_DOWN_REASON_ILLEGAL_STATE";
            case TEAR_DOWN_REASON_ONLY_ALLOWED_SINGLE_NETWORK:
                return "TEAR_DOWN_REASON_ONLY_ALLOWED_SINGLE_NETWORK";
            case TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED:
                return "TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED";
            default:
                return "UNKNOWN(" + reason + ")";
        }
    }

    /**
     * Convert event to string
     *
     * @param event The event
     * @return The event in string format.
     */
    private static @NonNull String eventToString(int event) {
        switch (event) {
            case EVENT_DATA_CONFIG_UPDATED:
                return "EVENT_DATA_CONFIG_UPDATED";
            case EVENT_ATTACH_NETWORK_REQUEST:
                return "EVENT_ATTACH_NETWORK_REQUEST";
            case EVENT_DETACH_NETWORK_REQUEST:
                return "EVENT_DETACH_NETWORK_REQUEST";
            case EVENT_ALLOCATE_PDU_SESSION_ID_RESPONSE:
                return "EVENT_ALLOCATE_PDU_SESSION_ID_RESPONSE";
            case EVENT_SETUP_DATA_NETWORK_RESPONSE:
                return "EVENT_SETUP_DATA_NETWORK_RESPONSE";
            case EVENT_TEAR_DOWN_NETWORK:
                return "EVENT_TEAR_DOWN_NETWORK";
            case EVENT_DATA_STATE_CHANGED:
                return "EVENT_DATA_STATE_CHANGED";
            case EVENT_SERVICE_STATE_CHANGED:
                return "EVENT_DATA_NETWORK_TYPE_REG_STATE_CHANGED";
            case EVENT_DETACH_ALL_NETWORK_REQUESTS:
                return "EVENT_DETACH_ALL_NETWORK_REQUESTS";
            case EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED:
                return "EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED";
            case EVENT_DISPLAY_INFO_CHANGED:
                return "EVENT_DISPLAY_INFO_CHANGED";
            case EVENT_START_HANDOVER:
                return "EVENT_START_HANDOVER";
            case EVENT_HANDOVER_RESPONSE:
                return "EVENT_HANDOVER_RESPONSE";
            case EVENT_SUBSCRIPTION_PLAN_OVERRIDE:
                return "EVENT_SUBSCRIPTION_PLAN_OVERRIDE";
            case EVENT_PCO_DATA_RECEIVED:
                return "EVENT_PCO_DATA_RECEIVED";
            case EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED:
                return "EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED";
            case EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE:
                return "EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE";
            case EVENT_STUCK_IN_TRANSIENT_STATE:
                return "EVENT_STUCK_IN_TRANSIENT_STATE";
            case EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET:
                return "EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET";
            case EVENT_VOICE_CALL_STARTED:
                return "EVENT_VOICE_CALL_STARTED";
            case EVENT_VOICE_CALL_ENDED:
                return "EVENT_VOICE_CALL_ENDED";
            case EVENT_CSS_INDICATOR_CHANGED:
                return "EVENT_CSS_INDICATOR_CHANGED";
            default:
                return "Unknown(" + event + ")";
        }
    }

    @Override
    public String toString() {
        return "[DataNetwork: " + mLogTag + ", " + (mDataProfile.getApnSetting() != null
                ? mDataProfile.getApnSetting().getApnName() : null) + ", state="
                + (getCurrentState() != null ? getCurrentState().getName() : null) + "]";
    }

    /**
     * @return The short name of the data network (e.g. DN-C-1)
     */
    public @NonNull String name() {
        return mLogTag;
    }

    /**
     * Trigger the anomaly report with the specified UUID.
     *
     * @param anomalyMsg Description of the event
     * @param uuid UUID associated with that event
     */
    private void reportAnomaly(@NonNull String anomalyMsg, @NonNull String uuid) {
        logl(anomalyMsg);
        AnomalyReporter.reportAnomaly(UUID.fromString(uuid), anomalyMsg, mPhone.getCarrierId());
    }

    /**
     * Log debug messages.
     * @param s debug messages
     */
    @Override
    protected void log(@NonNull String s) {
        Rlog.d(mLogTag, (getCurrentState() != null
                ? (getCurrentState().getName() + ": ") : "") + s);
    }

    /**
     * Log error messages.
     * @param s error messages
     */
    @Override
    protected void loge(@NonNull String s) {
        Rlog.e(mLogTag, (getCurrentState() != null
                ? (getCurrentState().getName() + ": ") : "") + s);
    }

    /**
     * Log verbose messages.
     * @param s error messages
     */
    @Override
    protected void logv(@NonNull String s) {
        if (VDBG) {
            Rlog.v(mLogTag, (getCurrentState() != null
                    ? (getCurrentState().getName() + ": ") : "") + s);
        }
    }

    /**
     * Log debug messages and also log into the local log.
     * @param s debug messages
     */
    private void logl(@NonNull String s) {
        log(s);
        mLocalLog.log((getCurrentState() != null ? (getCurrentState().getName() + ": ") : "") + s);
    }

    /**
     * Dump the state of DataNetwork
     *
     * @param fd File descriptor
     * @param printWriter Print writer
     * @param args Arguments
     */
    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
        super.dump(fd, pw, args);
        pw.println("Tag: " + name());
        pw.increaseIndent();
        pw.println("mSubId=" + mSubId);
        pw.println("mTransport=" + AccessNetworkConstants.transportTypeToString(mTransport));
        pw.println("WWAN cid=" + mCid.get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN));
        pw.println("WLAN cid=" + mCid.get(AccessNetworkConstants.TRANSPORT_TYPE_WLAN));
        pw.println("mNetworkScore=" + mNetworkScore);
        pw.println("mDataAllowedReason=" + mDataAllowedReason);
        pw.println("mPduSessionId=" + mPduSessionId);
        pw.println("mDataProfile=" + mDataProfile);
        pw.println("mNetworkCapabilities=" + mNetworkCapabilities);
        pw.println("mLinkProperties=" + mLinkProperties);
        pw.println("mNetworkSliceInfo=" + mNetworkSliceInfo);
        pw.println("mNetworkBandwidth=" + mNetworkBandwidth);
        pw.println("mTcpBufferSizes=" + mTcpBufferSizes);
        pw.println("mTelephonyDisplayInfo=" + mTelephonyDisplayInfo);
        pw.println("mTempNotMeteredSupported=" + mTempNotMeteredSupported);
        pw.println("mTempNotMetered=" + mTempNotMetered);
        pw.println("mCongested=" + mCongested);
        pw.println("mSuspended=" + mSuspended);
        pw.println("mDataCallResponse=" + mDataCallResponse);
        pw.println("mFailCause=" + DataFailCause.toString(mFailCause));
        pw.println("mAdministratorUids=" + Arrays.toString(mAdministratorUids));
        pw.println("mCarrierServicePackageUid=" + mCarrierServicePackageUid);
        pw.println("mEverConnected=" + mEverConnected);
        pw.println("mInvokedDataDeactivation=" + mInvokedDataDeactivation);

        pw.println("Attached network requests:");
        pw.increaseIndent();
        for (TelephonyNetworkRequest request : mAttachedNetworkRequestList) {
            pw.println(request);
        }
        pw.decreaseIndent();
        pw.println("mQosBearerSessions=" + mQosBearerSessions);

        mNetworkAgent.dump(fd, pw, args);
        pw.println("Local logs:");
        pw.increaseIndent();
        mLocalLog.dump(fd, pw, args);
        pw.decreaseIndent();
        pw.decreaseIndent();
        pw.println("---------------");
    }
}
