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

Commit a2e2e9cc authored by Chi Zhang's avatar Chi Zhang Committed by Kiwon Park
Browse files

Handle call RAT correctly according to bearer.

Bug: 236423393
Test: build && unit test && manual MO/MT for CS/VoLTE/WFC
Change-Id: Ic8da59a5c086dab923f7749c17f200d0f9db6edc
parent bb8155c6
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import android.os.SystemClock;
import android.telephony.AccessNetworkConstants;
import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.Annotation.NetworkType;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.telephony.ims.ImsReasonInfo;
@@ -358,7 +359,8 @@ public class ImsStats {
    public synchronized void onServiceStateChanged(ServiceState state) {
        if (mLastTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN
                && mLastRegistrationStats != null) {
            mLastRegistrationStats.rat = ServiceStateStats.getDataRat(state);
            mLastRegistrationStats.rat =
                    ServiceStateStats.getRat(state, NetworkRegistrationInfo.DOMAIN_PS);
        }
    }

@@ -395,7 +397,9 @@ public class ImsStats {

    @NetworkType
    private int getWwanPsRat() {
        return ServiceStateStats.getDataRat(mPhone.getServiceStateTracker().getServiceState());
        return ServiceStateStats.getRat(
                mPhone.getServiceStateTracker().getServiceState(),
                NetworkRegistrationInfo.DOMAIN_PS);
    }

    private ImsRegistrationStats getDefaultImsRegistrationStats() {
+38 −24
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.internal.telephony.metrics;

import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_CS;

import android.annotation.Nullable;
import android.os.SystemClock;
import android.telephony.AccessNetworkConstants;
@@ -85,7 +87,7 @@ public class ServiceStateStats {
        } else {
            CellularServiceState newState = new CellularServiceState();
            newState.voiceRat = getVoiceRat(mPhone, serviceState);
            newState.dataRat = getDataRat(serviceState);
            newState.dataRat = getRat(serviceState, NetworkRegistrationInfo.DOMAIN_PS);
            newState.voiceRoamingType = serviceState.getVoiceRoamingType();
            newState.dataRoamingType = serviceState.getDataRoamingType();
            newState.isEndc = isEndc(serviceState);
@@ -170,7 +172,10 @@ public class ServiceStateStats {
        }
        int chNumber = serviceState.getChannelNumber();
        int band;
        @NetworkType int rat = getRat(serviceState);
        @NetworkType int rat = getRat(serviceState, NetworkRegistrationInfo.DOMAIN_PS);
        if (rat == TelephonyManager.NETWORK_TYPE_UNKNOWN) {
            rat = serviceState.getVoiceNetworkType();
        }
        switch (rat) {
            case TelephonyManager.NETWORK_TYPE_GSM:
            case TelephonyManager.NETWORK_TYPE_GPRS:
@@ -231,6 +236,9 @@ public class ServiceStateStats {
    /**
     * Returns the current voice RAT from IMS registration if present, otherwise from the service
     * state.
     *
     * <p>If the device is not in service, {@code TelephonyManager.NETWORK_TYPE_UNKNOWN} is returned
     * despite that the device may have emergency service over a certain RAT.
     */
    static @NetworkType int getVoiceRat(Phone phone, @Nullable ServiceState state) {
        if (state == null) {
@@ -243,40 +251,45 @@ public class ServiceStateStats {
                // If IMS is over WWAN but WWAN PS is not in-service, then IMS RAT is invalid
                boolean isImsVoiceRatValid =
                        (imsVoiceRat == TelephonyManager.NETWORK_TYPE_IWLAN
                                || getDataRat(state) != TelephonyManager.NETWORK_TYPE_UNKNOWN);
                                || getRat(state, NetworkRegistrationInfo.DOMAIN_PS)
                                        != TelephonyManager.NETWORK_TYPE_UNKNOWN);
                return isImsVoiceRatValid ? imsVoiceRat : TelephonyManager.NETWORK_TYPE_UNKNOWN;
            }
        }

        // If WWAN CS is not in-service, we should return NETWORK_TYPE_UNKNOWN
        final NetworkRegistrationInfo wwanRegInfo =
                state.getNetworkRegistrationInfo(
                        NetworkRegistrationInfo.DOMAIN_CS,
                        AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
        return wwanRegInfo != null && wwanRegInfo.isInService()
                ? wwanRegInfo.getAccessNetworkTechnology()
                : TelephonyManager.NETWORK_TYPE_UNKNOWN;
        return getRat(state, NetworkRegistrationInfo.DOMAIN_CS);
    }

    /**
     * Returns RAT used by WWAN.
     * Returns the current voice RAT according to the bearer.
     *
     * <p>Returns PS WWAN RAT, or CS WWAN RAT if PS WWAN RAT is unavailable.
     * <p>If the device is not in service, {@code TelephonyManager.NETWORK_TYPE_UNKNOWN} is returned
     * despite that the device may have emergency service over a certain RAT.
     */
    private static @NetworkType int getRat(ServiceState state) {
        @NetworkType int rat = getDataRat(state);
        if (rat == TelephonyManager.NETWORK_TYPE_UNKNOWN) {
            rat = state.getVoiceNetworkType();
    static @NetworkType int getVoiceRat(Phone phone, @Nullable ServiceState state, int bearer) {
        if (state == null) {
            return TelephonyManager.NETWORK_TYPE_UNKNOWN;
        }
        ImsPhone imsPhone = (ImsPhone) phone.getImsPhone();
        if (bearer != VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_CS && imsPhone != null) {
            @NetworkType int imsVoiceRat = imsPhone.getImsStats().getImsVoiceRadioTech();
            if (imsVoiceRat != TelephonyManager.NETWORK_TYPE_UNKNOWN) {
                // If IMS is over WWAN but WWAN PS is not in-service, then IMS RAT is invalid
                boolean isImsVoiceRatValid =
                        (imsVoiceRat == TelephonyManager.NETWORK_TYPE_IWLAN
                                || getRat(state, NetworkRegistrationInfo.DOMAIN_PS)
                                        != TelephonyManager.NETWORK_TYPE_UNKNOWN);
                return isImsVoiceRatValid ? imsVoiceRat : TelephonyManager.NETWORK_TYPE_UNKNOWN;
            }
        }
        return rat;
        return getRat(state, NetworkRegistrationInfo.DOMAIN_CS);
    }

    /** Returns PS (data) RAT used by WWAN. */
    static @NetworkType int getDataRat(ServiceState state) {
    /** Returns RAT used by WWAN if WWAN is in service. */
    public static @NetworkType int getRat(
            ServiceState state, @NetworkRegistrationInfo.Domain int domain) {
        final NetworkRegistrationInfo wwanRegInfo =
                state.getNetworkRegistrationInfo(
                        NetworkRegistrationInfo.DOMAIN_PS,
                        AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
                        domain, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
        return wwanRegInfo != null && wwanRegInfo.isInService()
                ? wwanRegInfo.getAccessNetworkTechnology()
                : TelephonyManager.NETWORK_TYPE_UNKNOWN;
@@ -291,7 +304,8 @@ public class ServiceStateStats {
    }

    private static boolean isEndc(ServiceState state) {
        if (getDataRat(state) != TelephonyManager.NETWORK_TYPE_LTE) {
        if (getRat(state, NetworkRegistrationInfo.DOMAIN_PS)
                != TelephonyManager.NETWORK_TYPE_LTE) {
            return false;
        }
        int nrState = state.getNrState();
+15 −6
Original line number Diff line number Diff line
@@ -378,6 +378,10 @@ public class VoiceCallSessionStats {
                    VoiceCallSession proto = mCallProtos.get(id);
                    proto.srvccCompleted = true;
                    proto.bearerAtEnd = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_CS;
                    // Call RAT may have changed (e.g. IWLAN -> UMTS) due to bearer change
                    proto.ratAtEnd =
                            ServiceStateStats.getVoiceRat(
                                    mPhone, mPhone.getServiceState(), proto.bearerAtEnd);
                }
                break;
            case TelephonyManager.SRVCC_STATE_HANDOVER_FAILED:
@@ -432,7 +436,7 @@ public class VoiceCallSessionStats {
        }
        int bearer = getBearer(conn);
        ServiceState serviceState = getServiceState();
        @NetworkType int rat = ServiceStateStats.getVoiceRat(mPhone, serviceState);
        @NetworkType int rat = ServiceStateStats.getVoiceRat(mPhone, serviceState, bearer);

        VoiceCallSession proto = new VoiceCallSession();

@@ -570,7 +574,8 @@ public class VoiceCallSessionStats {
            proto.setupFailed = false;
            // Track RAT when voice call is connected.
            ServiceState serviceState = getServiceState();
            proto.ratAtConnected = ServiceStateStats.getVoiceRat(mPhone, serviceState);
            proto.ratAtConnected =
                    ServiceStateStats.getVoiceRat(mPhone, serviceState, proto.bearerAtEnd);
            // Reset list of codecs with the last codec at the present time. In this way, we
            // track codec quality only after call is connected and not while ringing.
            resetCodecList(conn);
@@ -578,18 +583,22 @@ public class VoiceCallSessionStats {
    }

    private void updateRatTracker(ServiceState state) {
        // RAT usage is not broken down by bearer. In case a CS call is made while there is IMS
        // voice registration, this may be inaccurate (i.e. there could be multiple RAT in use, but
        // we only pick the most feasible one).
        @NetworkType int rat = ServiceStateStats.getVoiceRat(mPhone, state);
        int band =
                (rat == TelephonyManager.NETWORK_TYPE_IWLAN) ? 0 : ServiceStateStats.getBand(state);

        mRatUsage.add(mPhone.getCarrierId(), rat, getTimeMillis(), getConnectionIds());

        for (int i = 0; i < mCallProtos.size(); i++) {
            VoiceCallSession proto = mCallProtos.valueAt(i);
            rat = ServiceStateStats.getVoiceRat(mPhone, state, proto.bearerAtEnd);
            if (proto.ratAtEnd != rat) {
                proto.ratSwitchCount++;
                proto.ratAtEnd = rat;
            }
            proto.bandAtEnd = band;
            proto.bandAtEnd = (rat == TelephonyManager.NETWORK_TYPE_IWLAN)
                            ? 0
                            : ServiceStateStats.getBand(state);
            // assuming that SIM carrier ID does not change during the call
        }
    }