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

Commit 794af810 authored by Hall Liu's avatar Hall Liu
Browse files

RTT outgoing initialization

Add support for dialing an outgoing call with RTT enabled from the start
    (refactors the dial methods to use DialArgs)
Add plumbing code to bubble up RTT initiation/termination events from
the IMS stack up to Telecom

Bug: 72156722
Bug: 71873552
Test: existing unit tests

Change-Id: I084f75d860ebc9837cf6156c1ebaaf4532343de1
Merged-In: I084f75d860ebc9837cf6156c1ebaaf4532343de1
parent 32e1e2bc
Loading
Loading
Loading
Loading
+6 −2
Original line number Original line Diff line number Diff line
@@ -964,7 +964,8 @@ public class CallManager {
        // FIXME Taken from klp-sprout-dev but setAudioMode was removed in L.
        // FIXME Taken from klp-sprout-dev but setAudioMode was removed in L.
        //mIsEccDialing = PhoneNumberUtils.isEmergencyNumber(dialString);
        //mIsEccDialing = PhoneNumberUtils.isEmergencyNumber(dialString);


        result = phone.dial(dialString, videoState);
        result = phone.dial(dialString, new PhoneInternalInterface.DialArgs.Builder<>()
                .setVideoState(videoState).build());


        if (VDBG) {
        if (VDBG) {
            Rlog.d(LOG_TAG, "End dial(" + phone + ", "+ dialString + ")");
            Rlog.d(LOG_TAG, "End dial(" + phone + ", "+ dialString + ")");
@@ -986,7 +987,10 @@ public class CallManager {
     */
     */
    public Connection dial(Phone phone, String dialString, UUSInfo uusInfo, int videoState)
    public Connection dial(Phone phone, String dialString, UUSInfo uusInfo, int videoState)
            throws CallStateException {
            throws CallStateException {
        return phone.dial(dialString, uusInfo, videoState, null);
        return phone.dial(dialString,
                new PhoneInternalInterface.DialArgs.Builder<>()
                        .setUusInfo(uusInfo)
                        .setVideoState(videoState).build());
    }
    }


    /**
    /**
+17 −0
Original line number Original line Diff line number Diff line
@@ -105,6 +105,8 @@ public abstract class Connection {
        public void onRttModifyRequestReceived();
        public void onRttModifyRequestReceived();
        public void onRttModifyResponseReceived(int status);
        public void onRttModifyResponseReceived(int status);
        public void onDisconnect(int cause);
        public void onDisconnect(int cause);
        public void onRttInitiated();
        public void onRttTerminated();
    }
    }


    /**
    /**
@@ -146,6 +148,10 @@ public abstract class Connection {
        public void onRttModifyResponseReceived(int status) {}
        public void onRttModifyResponseReceived(int status) {}
        @Override
        @Override
        public void onDisconnect(int cause) {}
        public void onDisconnect(int cause) {}
        @Override
        public void onRttInitiated() {}
        @Override
        public void onRttTerminated() {}
    }
    }


    public static final int AUDIO_QUALITY_STANDARD = 1;
    public static final int AUDIO_QUALITY_STANDARD = 1;
@@ -1062,6 +1068,17 @@ public abstract class Connection {
        }
        }
    }
    }


    public void onRttInitiated() {
        for (Listener l : mListeners) {
            l.onRttInitiated();
        }
    }

    public void onRttTerminated() {
        for (Listener l : mListeners) {
            l.onRttTerminated();
        }
    }
    /**
    /**
     * Notify interested parties that this connection disconnected.
     * Notify interested parties that this connection disconnected.
     * {@code TelephonyConnection}, for example, uses this.
     * {@code TelephonyConnection}, for example, uses this.
+19 −22
Original line number Original line Diff line number Diff line
@@ -28,6 +28,7 @@ import static com.android.internal.telephony.CommandsInterface.CF_REASON_NO_REPL
import static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDITIONAL;
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.CommandsInterface.SERVICE_CLASS_VOICE;


import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.BroadcastReceiver;
import android.content.ContentValues;
import android.content.ContentValues;
@@ -1034,14 +1035,9 @@ public class GsmCdmaPhone extends Phone {
    }
    }


    @Override
    @Override
    public Connection dial(String dialString, int videoState) throws CallStateException {
    public Connection dial(String dialString, @NonNull DialArgs dialArgs)
        return dial(dialString, null, videoState, null);
    }

    @Override
    public Connection dial(String dialString, UUSInfo uusInfo, int videoState, Bundle intentExtras)
            throws CallStateException {
            throws CallStateException {
        if (!isPhoneTypeGsm() && uusInfo != null) {
        if (!isPhoneTypeGsm() && dialArgs.uusInfo != null) {
            throw new CallStateException("Sending UUS information NOT supported in CDMA!");
            throw new CallStateException("Sending UUS information NOT supported in CDMA!");
        }
        }


@@ -1056,7 +1052,7 @@ public class GsmCdmaPhone extends Phone {
        boolean useImsForCall = isImsUseEnabled()
        boolean useImsForCall = isImsUseEnabled()
                 && imsPhone != null
                 && imsPhone != null
                 && (imsPhone.isVolteEnabled() || imsPhone.isWifiCallingEnabled() ||
                 && (imsPhone.isVolteEnabled() || imsPhone.isWifiCallingEnabled() ||
                 (imsPhone.isVideoEnabled() && VideoProfile.isVideo(videoState)))
                 (imsPhone.isVideoEnabled() && VideoProfile.isVideo(dialArgs.videoState)))
                 && (imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE);
                 && (imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE);


        boolean useImsForEmergency = imsPhone != null
        boolean useImsForEmergency = imsPhone != null
@@ -1093,7 +1089,7 @@ public class GsmCdmaPhone extends Phone {
        if ((useImsForCall && !isUt) || (isUt && useImsForUt) || useImsForEmergency) {
        if ((useImsForCall && !isUt) || (isUt && useImsForUt) || useImsForEmergency) {
            try {
            try {
                if (DBG) logd("Trying IMS PS call");
                if (DBG) logd("Trying IMS PS call");
                return imsPhone.dial(dialString, uusInfo, videoState, intentExtras);
                return imsPhone.dial(dialString, dialArgs);
            } catch (CallStateException e) {
            } catch (CallStateException e) {
                if (DBG) logd("IMS PS call exception " + e +
                if (DBG) logd("IMS PS call exception " + e +
                        "useImsForCall =" + useImsForCall + ", imsPhone =" + imsPhone);
                        "useImsForCall =" + useImsForCall + ", imsPhone =" + imsPhone);
@@ -1116,7 +1112,7 @@ public class GsmCdmaPhone extends Phone {
        }
        }
        // Check non-emergency voice CS call - shouldn't dial when POWER_OFF
        // Check non-emergency voice CS call - shouldn't dial when POWER_OFF
        if (mSST != null && mSST.mSS.getState() == ServiceState.STATE_POWER_OFF /* CS POWER_OFF */
        if (mSST != null && mSST.mSS.getState() == ServiceState.STATE_POWER_OFF /* CS POWER_OFF */
                && !VideoProfile.isVideo(videoState) /* voice call */
                && !VideoProfile.isVideo(dialArgs.videoState) /* voice call */
                && !isEmergency /* non-emergency call */) {
                && !isEmergency /* non-emergency call */) {
            throw new CallStateException(
            throw new CallStateException(
                CallStateException.ERROR_POWER_OFF,
                CallStateException.ERROR_POWER_OFF,
@@ -1128,7 +1124,7 @@ public class GsmCdmaPhone extends Phone {
                && mSST.mSS.getState() == ServiceState.STATE_OUT_OF_SERVICE /* CS out of service */
                && mSST.mSS.getState() == ServiceState.STATE_OUT_OF_SERVICE /* CS out of service */
                && !(mSST.mSS.getDataRegState() == ServiceState.STATE_IN_SERVICE
                && !(mSST.mSS.getDataRegState() == ServiceState.STATE_IN_SERVICE
                    && ServiceState.isLte(mSST.mSS.getRilDataRadioTechnology())) /* PS not in LTE */
                    && ServiceState.isLte(mSST.mSS.getRilDataRadioTechnology())) /* PS not in LTE */
                && !VideoProfile.isVideo(videoState) /* voice call */
                && !VideoProfile.isVideo(dialArgs.videoState) /* voice call */
                && !isEmergency /* non-emergency call */) {
                && !isEmergency /* non-emergency call */) {
            throw new CallStateException(
            throw new CallStateException(
                CallStateException.ERROR_OUT_OF_SERVICE,
                CallStateException.ERROR_OUT_OF_SERVICE,
@@ -1137,9 +1133,11 @@ public class GsmCdmaPhone extends Phone {
        if (DBG) logd("Trying (non-IMS) CS call");
        if (DBG) logd("Trying (non-IMS) CS call");


        if (isPhoneTypeGsm()) {
        if (isPhoneTypeGsm()) {
            return dialInternal(dialString, null, VideoProfile.STATE_AUDIO_ONLY, intentExtras);
            return dialInternal(dialString, new DialArgs.Builder<>()
                    .setIntentExtras(dialArgs.intentExtras)
                    .build());
        } else {
        } else {
            return dialInternal(dialString, null, videoState, intentExtras);
            return dialInternal(dialString, dialArgs);
        }
        }
    }
    }


@@ -1180,14 +1178,13 @@ public class GsmCdmaPhone extends Phone {
    }
    }


    @Override
    @Override
    protected Connection dialInternal(String dialString, UUSInfo uusInfo, int videoState,
    protected Connection dialInternal(String dialString, DialArgs dialArgs)
                                      Bundle intentExtras)
            throws CallStateException {
            throws CallStateException {
        return dialInternal(dialString, uusInfo, videoState, intentExtras, null);
        return dialInternal(dialString, dialArgs, null);
    }
    }


    protected Connection dialInternal(String dialString, UUSInfo uusInfo, int videoState,
    protected Connection dialInternal(String dialString, DialArgs dialArgs,
                                      Bundle intentExtras, ResultReceiver wrappedCallback)
            ResultReceiver wrappedCallback)
            throws CallStateException {
            throws CallStateException {


        // Need to make sure dialString gets parsed properly
        // Need to make sure dialString gets parsed properly
@@ -1206,9 +1203,10 @@ public class GsmCdmaPhone extends Phone {
            if (DBG) logd("dialInternal: dialing w/ mmi '" + mmi + "'...");
            if (DBG) logd("dialInternal: dialing w/ mmi '" + mmi + "'...");


            if (mmi == null) {
            if (mmi == null) {
                return mCT.dial(newDialString, uusInfo, intentExtras);
                return mCT.dial(newDialString, dialArgs.uusInfo, dialArgs.intentExtras);
            } else if (mmi.isTemporaryModeCLIR()) {
            } else if (mmi.isTemporaryModeCLIR()) {
                return mCT.dial(mmi.mDialingNumber, mmi.getCLIRMode(), uusInfo, intentExtras);
                return mCT.dial(mmi.mDialingNumber, mmi.getCLIRMode(), dialArgs.uusInfo,
                        dialArgs.intentExtras);
            } else {
            } else {
                mPendingMMIs.add(mmi);
                mPendingMMIs.add(mmi);
                mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
                mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
@@ -1281,8 +1279,7 @@ public class GsmCdmaPhone extends Phone {


        // Try USSD over GSM.
        // Try USSD over GSM.
        try {
        try {
            dialInternal(ussdRequest, null, VideoProfile.STATE_AUDIO_ONLY, null,
            dialInternal(ussdRequest, new DialArgs.Builder<>().build(), wrappedCallback);
                    wrappedCallback);
        } catch (Exception e) {
        } catch (Exception e) {
            logd("handleUssdRequest: exception" + e);
            logd("handleUssdRequest: exception" + e);
            return false;
            return false;
+3 −6
Original line number Original line Diff line number Diff line
@@ -665,7 +665,7 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
                    String dialString = (String) ar.result;
                    String dialString = (String) ar.result;
                    if (TextUtils.isEmpty(dialString)) return;
                    if (TextUtils.isEmpty(dialString)) return;
                    try {
                    try {
                        dialInternal(dialString, null, VideoProfile.STATE_AUDIO_ONLY, null);
                        dialInternal(dialString, new DialArgs.Builder().build());
                    } catch (CallStateException e) {
                    } catch (CallStateException e) {
                        Rlog.e(LOG_TAG, "silent redial failed: " + e);
                        Rlog.e(LOG_TAG, "silent redial failed: " + e);
                    }
                    }
@@ -3049,14 +3049,11 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
     * Dials a number.
     * Dials a number.
     *
     *
     * @param dialString The number to dial.
     * @param dialString The number to dial.
     * @param uusInfo The UUSInfo.
     * @param dialArgs Parameters to dial with.
     * @param videoState The video state for the call.
     * @param intentExtras Extras from the original CALL intent.
     * @return The Connection.
     * @return The Connection.
     * @throws CallStateException
     * @throws CallStateException
     */
     */
    protected Connection dialInternal(
    protected Connection dialInternal(String dialString, DialArgs dialArgs)
            String dialString, UUSInfo uusInfo, int videoState, Bundle intentExtras)
            throws CallStateException {
            throws CallStateException {
        // dialInternal shall be overriden by GsmCdmaPhone
        // dialInternal shall be overriden by GsmCdmaPhone
        return null;
        return null;
+49 −23
Original line number Original line Diff line number Diff line
@@ -16,12 +16,14 @@


package com.android.internal.telephony;
package com.android.internal.telephony;


import android.annotation.NonNull;
import android.os.Bundle;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler;
import android.os.Message;
import android.os.Message;
import android.os.ResultReceiver;
import android.os.ResultReceiver;
import android.os.WorkSource;
import android.os.WorkSource;
import android.telephony.CarrierConfigManager;
import android.telephony.CarrierConfigManager;
import android.telecom.VideoProfile;
import android.telephony.CellLocation;
import android.telephony.CellLocation;
import android.telephony.ImsiEncryptionInfo;
import android.telephony.ImsiEncryptionInfo;
import android.telephony.NetworkScanRequest;
import android.telephony.NetworkScanRequest;
@@ -62,6 +64,51 @@ public interface PhoneInternalInterface {
      UNKNOWN, SWITCH, SEPARATE, TRANSFER, CONFERENCE, REJECT, HANGUP, RESUME, HOLD;
      UNKNOWN, SWITCH, SEPARATE, TRANSFER, CONFERENCE, REJECT, HANGUP, RESUME, HOLD;
    }
    }


    /**
     * Arguments that control behavior of dialing a call.
     */
    public static class DialArgs {
        public static class Builder<T extends Builder<T>> {
            protected UUSInfo mUusInfo;
            protected int mVideoState = VideoProfile.STATE_AUDIO_ONLY;
            protected Bundle mIntentExtras;

            public T setUusInfo(UUSInfo uusInfo) {
                mUusInfo = uusInfo;
                return (T) this;
            }

            public T setVideoState(int videoState) {
                mVideoState = videoState;
                return (T) this;
            }

            public T setIntentExtras(Bundle intentExtras) {
                this.mIntentExtras = intentExtras;
                return (T) this;
            }

            public PhoneInternalInterface.DialArgs build() {
                return new DialArgs(this);
            }
        }

        /** The UUSInfo */
        public final UUSInfo uusInfo;

        /** The desired video state for the connection. */
        public final int videoState;

        /** The extras from the original CALL intent. */
        public final Bundle intentExtras;

        protected DialArgs(Builder b) {
            this.uusInfo = b.mUusInfo;
            this.videoState = b.mVideoState;
            this.intentExtras = b.mIntentExtras;
        }
    }

    // "Features" accessible through the connectivity manager
    // "Features" accessible through the connectivity manager
    static final String FEATURE_ENABLE_MMS = "enableMMS";
    static final String FEATURE_ENABLE_MMS = "enableMMS";
    static final String FEATURE_ENABLE_SUPL = "enableSUPL";
    static final String FEATURE_ENABLE_SUPL = "enableSUPL";
@@ -401,34 +448,13 @@ public interface PhoneInternalInterface {
     * assigned) until PhoneStateChanged notification has occurred.
     * assigned) until PhoneStateChanged notification has occurred.
     *
     *
     * @param dialString The dial string.
     * @param dialString The dial string.
     * @param videoState The desired video state for the connection.
     * @param dialArgs Parameters to perform the dial with.
     * @exception CallStateException if a new outgoing call is not currently
     * possible because no more call slots exist or a call exists that is
     * dialing, alerting, ringing, or waiting.  Other errors are
     * handled asynchronously.
     */
    Connection dial(String dialString, int videoState) throws CallStateException;

    /**
     * Initiate a new voice connection with supplementary User to User
     * Information. This happens asynchronously, so you cannot assume the audio
     * path is connected (or a call index has been assigned) until
     * PhoneStateChanged notification has occurred.
     *
     * NOTE: If adding another parameter, consider creating a DialArgs parameter instead to
     * encapsulate all dial arguments and decrease scaffolding headache.
     *
     * @param dialString The dial string.
     * @param uusInfo The UUSInfo.
     * @param videoState The desired video state for the connection.
     * @param intentExtras The extras from the original CALL intent.
     * @exception CallStateException if a new outgoing call is not currently
     * @exception CallStateException if a new outgoing call is not currently
     *                possible because no more call slots exist or a call exists
     *                possible because no more call slots exist or a call exists
     *                that is dialing, alerting, ringing, or waiting. Other
     *                that is dialing, alerting, ringing, or waiting. Other
     *                errors are handled asynchronously.
     *                errors are handled asynchronously.
     */
     */
    Connection dial(String dialString, UUSInfo uusInfo, int videoState, Bundle intentExtras)
    Connection dial(String dialString, @NonNull DialArgs dialArgs) throws CallStateException;
            throws CallStateException;


    /**
    /**
     * Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated
     * Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated
Loading