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

Commit b45853e3 authored by Hunsuk Choi's avatar Hunsuk Choi
Browse files

Implement the domain selection of supplementary services over Ut

The keys of Carrier config and the state of transport layer are used
to determine the UT capability.

The following keys are used:
- KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL
- ImsSs.KEY_UT_REQUIRES_IMS_REGISTRATION_BOOL
- ImsSs.KEY_UT_SERVER_BASED_SERVICES_INT_ARRAY
- ImsSs.KEY_UT_SUPPORTED_WHEN_PS_DATA_OFF_BOOL
- ImsSs.KEY_UT_SUPPORTED_WHEN_ROAMING_BOOL
- ImsSs.KEY_USE_CSFB_ON_XCAP_OVER_UT_FAILURE_BOOL
- ImsSs.KEY_XCAP_OVER_UT_SUPPORTED_RATS_INT_ARRAY

Bug: 202463163
Test: atest

Change-Id: Ice627a3c8dd4ec9d69e18ad426cb703096834bd5
(cherry picked from commit 7addc57c93951af3651492706bcb13339d479ba4)
Merged-In: Ice627a3c8dd4ec9d69e18ad426cb703096834bd5
parent 4327d1bd
Loading
Loading
Loading
Loading
+145 −42
Original line number Diff line number Diff line
@@ -29,6 +29,9 @@ import static com.android.internal.telephony.CommandsInterface.CF_REASON_NOT_REA
import static com.android.internal.telephony.CommandsInterface.CF_REASON_NO_REPLY;
import static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDITIONAL;
import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_VOICE;
import static com.android.internal.telephony.SsDomainController.SS_CLIP;
import static com.android.internal.telephony.SsDomainController.SS_CLIR;
import static com.android.internal.telephony.SsDomainController.SS_CW;

import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -264,6 +267,8 @@ public class GsmCdmaPhone extends Phone {
    private boolean mResetModemOnRadioTechnologyChange = false;
    private boolean mSsOverCdmaSupported = false;

    private SsDomainController mSsDomainController;

    private int mRilVersion;
    private boolean mBroadcastEmergencyCallStateChanges = false;
    private @ServiceState.RegState int mTelecomVoiceServiceStateOverride =
@@ -399,6 +404,8 @@ public class GsmCdmaPhone extends Phone {
        subMan.addOnSubscriptionsChangedListener(
                new HandlerExecutor(this), mSubscriptionsChangedListener);

        mSsDomainController = new SsDomainController(this);

        logd("GsmCdmaPhone: constructor: sub = " + mPhoneId);
    }

@@ -1464,9 +1471,10 @@ public class GsmCdmaPhone extends Phone {
                stripSeparators(dialString));
        boolean isMmiCode = (dialPart.startsWith("*") || dialPart.startsWith("#"))
                && dialPart.endsWith("#");
        boolean isSuppServiceCode = ImsPhoneMmiCode.isSuppServiceCodes(dialPart, this);
        boolean isPotentialUssdCode = isMmiCode && !isSuppServiceCode;
        boolean useImsForUt = imsPhone != null && imsPhone.isUtEnabled();
        SsDomainController.SuppServiceRoutingInfo ssInfo =
                ImsPhoneMmiCode.getSuppServiceRoutingInfo(dialPart, this);
        boolean isPotentialUssdCode = isMmiCode && (ssInfo == null);
        boolean useImsForUt = ssInfo != null && ssInfo.useSsOverUt();
        boolean useImsForCall = useImsForCall(dialArgs)
                && (isWpsCall ? allowWpsOverIms : true);

@@ -1477,7 +1485,8 @@ public class GsmCdmaPhone extends Phone {
                    + ", useImsForEmergency=" + useImsForEmergency
                    + ", useImsForUt=" + useImsForUt
                    + ", isUt=" + isMmiCode
                    + ", isSuppServiceCode=" + isSuppServiceCode
                    + ", isSuppServiceCode=" + (ssInfo != null)
                    + ", useSsOverUt=" + (ssInfo != null && ssInfo.useSsOverUt())
                    + ", isPotentialUssdCode=" + isPotentialUssdCode
                    + ", isWpsCall=" + isWpsCall
                    + ", allowWpsOverIms=" + allowWpsOverIms
@@ -1533,6 +1542,10 @@ public class GsmCdmaPhone extends Phone {
            }
        }

        if (ssInfo != null && !ssInfo.supportsCsfb()) {
            throw new CallStateException("not support csfb for supplementary services");
        }

        if (mSST != null && mSST.mSS.getState() == ServiceState.STATE_OUT_OF_SERVICE
                && mSST.mSS.getDataRegistrationState() != ServiceState.STATE_IN_SERVICE
                && !isEmergency) {
@@ -2323,12 +2336,36 @@ public class GsmCdmaPhone extends Phone {
        mSsOverCdmaSupported = b.getBoolean(CarrierConfigManager.KEY_SUPPORT_SS_OVER_CDMA_BOOL);
    }

    private void updateSsOverUtConfig(PersistableBundle b) {
        mSsDomainController.updateSsOverUtConfig(b);
    }

    @Override
    public boolean useSsOverIms(Message onComplete) {
    public SsDomainController getSsDomainController() {
        return mSsDomainController;
    }

    /** Checks the static configuration for the given Call Barring service. */
    public boolean useCbOverUt(String facility) {
        return mSsDomainController.useCbOverUt(facility);
    }

    /** Checks the static configuration for the given Call Forwarding service. */
    public boolean useCfOverUt(int reason) {
        return mSsDomainController.useCfOverUt(reason);
    }

    /** Checks the static configuration for the given supplementary service. */
    public boolean useSsOverUt(String service) {
        return mSsDomainController.useSsOverUt(service);
    }

    @Override
    public boolean useSsOverUt(Message onComplete) {
        boolean isUtEnabled = isUtEnabled();

        Rlog.d(LOG_TAG, "useSsOverIms: isUtEnabled()= " + isUtEnabled +
                " isCsRetry(onComplete))= " + isCsRetry(onComplete));
        Rlog.d(LOG_TAG, "useSsOverUt: isUtEnabled()= " + isUtEnabled
                + " isCsRetry(onComplete))= " + isCsRetry(onComplete));

        if (isUtEnabled && !isCsRetry(onComplete)) {
            return true;
@@ -2336,6 +2373,24 @@ public class GsmCdmaPhone extends Phone {
        return false;
    }

    /**
     * Returns whether CSFB is supported for supplementary services.
     */
    public boolean supportCsfbForSs() {
        return mSsDomainController.supportCsfb();
    }

    /**
     * Sends response indicating no nework is available for supplementary services.
     */
    private void responseInvalidState(Message onComplete) {
        if (onComplete == null) return;
        AsyncResult.forMessage(onComplete, null,
                new CommandException(CommandException.Error.INVALID_STATE,
                        "No network available for supplementary services"));
        onComplete.sendToTarget();
    }

    @Override
    public void getCallForwardingOption(int commandInterfaceCFReason, Message onComplete) {
        getCallForwardingOption(commandInterfaceCFReason,
@@ -2355,10 +2410,16 @@ public class GsmCdmaPhone extends Phone {
        }

        Phone imsPhone = mImsPhone;
        if (useSsOverIms(onComplete)) {
            imsPhone.getCallForwardingOption(commandInterfaceCFReason, serviceClass, onComplete);
        if (useCfOverUt(commandInterfaceCFReason)) {
            if (useSsOverUt(onComplete)) {
                imsPhone.getCallForwardingOption(commandInterfaceCFReason,
                        serviceClass, onComplete);
                return;
            } else if (!supportCsfbForSs()) {
                responseInvalidState(onComplete);
                return;
            }
        }

        if (isPhoneTypeGsm()) {
            if (isValidCommandInterfaceCFReason(commandInterfaceCFReason)) {
@@ -2414,10 +2475,15 @@ public class GsmCdmaPhone extends Phone {
        }

        Phone imsPhone = mImsPhone;
        if (useSsOverIms(onComplete)) {
        if (useCfOverUt(commandInterfaceCFReason)) {
            if (useSsOverUt(onComplete)) {
                imsPhone.setCallForwardingOption(commandInterfaceCFAction, commandInterfaceCFReason,
                        dialingNumber, serviceClass, timerSeconds, onComplete);
                return;
            } else if (!supportCsfbForSs()) {
                responseInvalidState(onComplete);
                return;
            }
        }

        if (isPhoneTypeGsm()) {
@@ -2476,9 +2542,14 @@ public class GsmCdmaPhone extends Phone {
        }

        Phone imsPhone = mImsPhone;
        if (useSsOverIms(onComplete)) {
        if (useCbOverUt(facility)) {
            if (useSsOverUt(onComplete)) {
                imsPhone.getCallBarring(facility, password, onComplete, serviceClass);
                return;
            } else if (!supportCsfbForSs()) {
                responseInvalidState(onComplete);
                return;
            }
        }

        if (isPhoneTypeGsm()) {
@@ -2503,9 +2574,14 @@ public class GsmCdmaPhone extends Phone {
        }

        Phone imsPhone = mImsPhone;
        if (useSsOverIms(onComplete)) {
        if (useCbOverUt(facility)) {
            if (useSsOverUt(onComplete)) {
                imsPhone.setCallBarring(facility, lockState, password, onComplete, serviceClass);
                return;
            } else if (!supportCsfbForSs()) {
                responseInvalidState(onComplete);
                return;
            }
        }

        if (isPhoneTypeGsm()) {
@@ -2555,9 +2631,14 @@ public class GsmCdmaPhone extends Phone {
        }

        Phone imsPhone = mImsPhone;
        if (useSsOverIms(onComplete)) {
        if (useSsOverUt(SS_CLIR)) {
            if (useSsOverUt(onComplete)) {
                imsPhone.getOutgoingCallerIdDisplay(onComplete);
                return;
            } else if (!supportCsfbForSs()) {
                responseInvalidState(onComplete);
                return;
            }
        }

        if (isPhoneTypeGsm()) {
@@ -2582,9 +2663,14 @@ public class GsmCdmaPhone extends Phone {
        }

        Phone imsPhone = mImsPhone;
        if (useSsOverIms(onComplete)) {
        if (useSsOverUt(SS_CLIR)) {
            if (useSsOverUt(onComplete)) {
                imsPhone.setOutgoingCallerIdDisplay(commandInterfaceCLIRMode, onComplete);
                return;
            } else if (!supportCsfbForSs()) {
                responseInvalidState(onComplete);
                return;
            }
        }

        if (isPhoneTypeGsm()) {
@@ -2612,9 +2698,14 @@ public class GsmCdmaPhone extends Phone {
        }

        Phone imsPhone = mImsPhone;
        if (useSsOverIms(onComplete)) {
        if (useSsOverUt(SS_CLIP)) {
            if (useSsOverUt(onComplete)) {
                imsPhone.queryCLIP(onComplete);
                return;
            } else if (!supportCsfbForSs()) {
                responseInvalidState(onComplete);
                return;
            }
        }

        if (isPhoneTypeGsm()) {
@@ -2638,9 +2729,14 @@ public class GsmCdmaPhone extends Phone {
        }

        Phone imsPhone = mImsPhone;
        if (useSsOverIms(onComplete)) {
        if (useSsOverUt(SS_CW)) {
            if (useSsOverUt(onComplete)) {
                imsPhone.getCallWaiting(onComplete);
                return;
            } else if (!supportCsfbForSs()) {
                responseInvalidState(onComplete);
                return;
            }
        }

        if (isPhoneTypeGsm()) {
@@ -2689,9 +2785,14 @@ public class GsmCdmaPhone extends Phone {
        }

        Phone imsPhone = mImsPhone;
        if (useSsOverIms(onComplete)) {
        if (useSsOverUt(SS_CW)) {
            if (useSsOverUt(onComplete)) {
                imsPhone.setCallWaiting(enable, onComplete);
                return;
            } else if (!supportCsfbForSs()) {
                responseInvalidState(onComplete);
                return;
            }
        }

        if (isPhoneTypeGsm()) {
@@ -3176,6 +3277,7 @@ public class GsmCdmaPhone extends Phone {
                updateVoNrSettings(b);
                updateSsOverCdmaSupported(b);
                loadAllowedNetworksFromSubscriptionDatabase();
                updateSsOverUtConfig(b);
                // Obtain new radio capabilities from the modem, since some are SIM-dependent
                mCi.getRadioCapability(obtainMessage(EVENT_GET_RADIO_CAPABILITY));
                break;
@@ -4399,6 +4501,13 @@ public class GsmCdmaPhone extends Phone {
                        + ServiceState.rilServiceStateToString(mTelecomVoiceServiceStateOverride)
                        + ")");
        pw.flush();

        try {
            mSsDomainController.dump(pw);
        } catch (Exception e) {
            e.printStackTrace();
        }
        pw.flush();
    }

    @Override
@@ -4695,13 +4804,7 @@ public class GsmCdmaPhone extends Phone {

    @Override
    public boolean isUtEnabled() {
        Phone imsPhone = mImsPhone;
        if (imsPhone != null) {
            return imsPhone.isUtEnabled();
        } else {
            logd("isUtEnabled: called for GsmCdma");
            return false;
        }
        return mSsDomainController.isUtEnabled();
    }

    public String getDtmfToneDelayKey() {
+11 −1
Original line number Diff line number Diff line
@@ -4865,7 +4865,17 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
        return null;
    }

    public boolean useSsOverIms(Message onComplete) {
    /**
     * Returns the instance of SsDomainController
     */
    public SsDomainController getSsDomainController() {
        return null;
    }

    /**
     * Returns whether it will be served with Ut or not.
     */
    public boolean useSsOverUt(Message onComplete) {
        return false;
    }

+566 −0

File added.

Preview size limit exceeded, changes collapsed.

+15 −0
Original line number Diff line number Diff line
@@ -1048,6 +1048,9 @@ public final class GsmMmiCode extends Handler implements MmiCode {
                throw new RuntimeException ("Invalid or Unsupported MMI Code");
            } else if (mSc != null && mSc.equals(SC_CLIP)) {
                Rlog.d(LOG_TAG, "processCode: is CLIP");
                if (!mPhone.supportCsfbForSs()) {
                    throw new RuntimeException("No network to support supplementary services");
                }
                if (isInterrogate()) {
                    mPhone.mCi.queryCLIP(
                            obtainMessage(EVENT_QUERY_COMPLETE, this));
@@ -1056,6 +1059,9 @@ public final class GsmMmiCode extends Handler implements MmiCode {
                }
            } else if (mSc != null && mSc.equals(SC_CLIR)) {
                Rlog.d(LOG_TAG, "processCode: is CLIR");
                if (!mPhone.supportCsfbForSs()) {
                    throw new RuntimeException("No network to support supplementary services");
                }
                if (isActivate() && !mPhone.isClirActivationAndDeactivationPrevented()) {
                    mPhone.mCi.setCLIR(CommandsInterface.CLIR_INVOCATION,
                        obtainMessage(EVENT_SET_COMPLETE, this));
@@ -1070,6 +1076,9 @@ public final class GsmMmiCode extends Handler implements MmiCode {
                }
            } else if (isServiceCodeCallForwarding(mSc)) {
                Rlog.d(LOG_TAG, "processCode: is CF");
                if (!mPhone.supportCsfbForSs()) {
                    throw new RuntimeException("No network to support supplementary services");
                }

                String dialingNumber = mSia;
                int serviceClass = siToServiceClass(mSib);
@@ -1117,6 +1126,9 @@ public final class GsmMmiCode extends Handler implements MmiCode {
                                    isEnableDesired, this));
                }
            } else if (isServiceCodeCallBarring(mSc)) {
                if (!mPhone.supportCsfbForSs()) {
                    throw new RuntimeException("No network to support supplementary services");
                }
                // sia = password
                // sib = basic service group

@@ -1164,6 +1176,9 @@ public final class GsmMmiCode extends Handler implements MmiCode {
                }

            } else if (mSc != null && mSc.equals(SC_WAIT)) {
                if (!mPhone.supportCsfbForSs()) {
                    throw new RuntimeException("No network to support supplementary services");
                }
                // sia = basic service group
                int serviceClass = siToServiceClass(mSia);

+46 −28
Original line number Diff line number Diff line
@@ -32,10 +32,14 @@ import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_PAC
import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_PAD;
import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_SMS;
import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_VOICE;
import static com.android.internal.telephony.SsDomainController.SS_CLIP;
import static com.android.internal.telephony.SsDomainController.SS_CLIR;
import static com.android.internal.telephony.SsDomainController.SS_COLP;
import static com.android.internal.telephony.SsDomainController.SS_COLR;
import static com.android.internal.telephony.SsDomainController.SS_CW;

import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Resources;
import android.os.AsyncResult;
import android.os.Build;
import android.os.Handler;
@@ -62,6 +66,7 @@ import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.MmiCode;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.SsDomainController;
import com.android.internal.telephony.gsm.GsmMmiCode;
import com.android.internal.telephony.uicc.IccRecords;
import com.android.telephony.Rlog;
@@ -487,17 +492,12 @@ public final class ImsPhoneMmiCode extends Handler implements MmiCode {

    static boolean
    isServiceCodeCallBarring(String sc) {
        Resources resource = Resources.getSystem();
        if (sc != null) {
            String[] barringMMI = resource.getStringArray(
                com.android.internal.R.array.config_callBarringMMI_for_ims);
            if (barringMMI != null) {
                for (String match : barringMMI) {
                    if (sc.equals(match)) return true;
                }
            }
        }
        return false;
        return sc != null
                && (sc.equals(SC_BAOC)
                || sc.equals(SC_BAOIC) || sc.equals(SC_BAOICxH)
                || sc.equals(SC_BAIC) || sc.equals(SC_BAICr)
                || sc.equals(SC_BA_ALL) || sc.equals(SC_BA_MO)
                || sc.equals(SC_BA_MT));
    }

    static boolean isPinPukCommand(String sc) {
@@ -509,9 +509,11 @@ public final class ImsPhoneMmiCode extends Handler implements MmiCode {
     * Whether the dial string is supplementary service code.
     *
     * @param dialString The dial string.
     * @return true if the dial string is supplementary service code, and {@code false} otherwise.
     * @return an instance of SsDomainController.SuppServiceRoutingInfo if the dial string
     * is supplementary service code, and null otherwise.
     */
    public static boolean isSuppServiceCodes(String dialString, Phone phone) {
    public static SsDomainController.SuppServiceRoutingInfo getSuppServiceRoutingInfo(
            String dialString, Phone phone) {
        if (phone != null && phone.getServiceState().getVoiceRoaming()
                && phone.getDefaultPhone().supportsConversionOfCdmaCallerIdMmiCodesWhileRoaming()) {
            /* The CDMA MMI coded dialString will be converted to a 3GPP MMI Coded dialString
@@ -520,38 +522,54 @@ public final class ImsPhoneMmiCode extends Handler implements MmiCode {
            dialString = convertCdmaMmiCodesTo3gppMmiCodes(dialString);
        }

        if (phone == null) return null;
        return getSuppServiceRoutingInfo(dialString, phone.getSsDomainController());
    }

    /**
     * Whether the dial string is supplementary service code.
     */
    @VisibleForTesting
    public static SsDomainController.SuppServiceRoutingInfo getSuppServiceRoutingInfo(
            String dialString, SsDomainController controller) {
        Matcher m = sPatternSuppService.matcher(dialString);
        if (m.matches()) {
            String sc = makeEmptyNull(m.group(MATCH_GROUP_SERVICE_CODE));
            if (isServiceCodeCallForwarding(sc)) {
                return true;
                return controller.getSuppServiceRoutingInfoForCf(scToCallForwardReason(sc));
            } else if (isServiceCodeCallBarring(sc)) {
                return true;
                return controller.getSuppServiceRoutingInfoForCb(scToBarringFacility(sc));
            } else if (sc != null && sc.equals(SC_CFUT)) {
                return true;
                // for backward compatibility, not specified by CarrierConfig
                return SsDomainController.SS_ROUTING_OVER_UT;
            } else if (sc != null && sc.equals(SC_CLIP)) {
                return true;
                return controller.getSuppServiceRoutingInfoForSs(SS_CLIP);
            } else if (sc != null && sc.equals(SC_CLIR)) {
                return true;
                return controller.getSuppServiceRoutingInfoForSs(SS_CLIR);
            } else if (sc != null && sc.equals(SC_COLP)) {
                return true;
                return controller.getSuppServiceRoutingInfoForSs(SS_COLP);
            } else if (sc != null && sc.equals(SC_COLR)) {
                return true;
                return controller.getSuppServiceRoutingInfoForSs(SS_COLR);
            } else if (sc != null && sc.equals(SC_CNAP)) {
                return true;
                // for backward compatibility, not specified by CarrierConfig
                return SsDomainController.SS_ROUTING_OVER_UT;
            } else if (sc != null && sc.equals(SC_BS_MT)) {
                return true;
                return controller.getSuppServiceRoutingInfoForCb(
                        SsDomainController.CB_FACILITY_BIL);
            } else if (sc != null && sc.equals(SC_BAICa)) {
                return true;
                return controller.getSuppServiceRoutingInfoForCb(
                        SsDomainController.CB_FACILITY_ACR);
            } else if (sc != null && sc.equals(SC_PWD)) {
                return true;
                // for backward compatibility, not specified by CarrierConfig
                return SsDomainController.SS_ROUTING_OVER_UT;
            } else if (sc != null && sc.equals(SC_WAIT)) {
                return true;
                return controller.getSuppServiceRoutingInfoForSs(SS_CW);
            } else if (isPinPukCommand(sc)) {
                return true;
                // for backward compatibility, not specified by CarrierConfig
                return SsDomainController.SS_ROUTING_OVER_UT;
            }
        }
        return false;
        return null;
    }

    static String
Loading