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

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

Merge "Fix issues with MMI/USSD codes." into oc-dev

parents 91b7e824 feefaf43
Loading
Loading
Loading
Loading
+35 −46
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
import com.android.internal.telephony.cdma.EriManager;
import com.android.internal.telephony.gsm.GsmMmiCode;
import com.android.internal.telephony.gsm.SuppServiceNotification;
import com.android.internal.telephony.imsphone.ImsPhone;
import com.android.internal.telephony.test.SimulatedRadioControl;
import com.android.internal.telephony.uicc.IccCardProxy;
import com.android.internal.telephony.uicc.IccException;
@@ -155,7 +156,6 @@ public class GsmCdmaPhone extends Phone {
    public GsmCdmaCallTracker mCT;
    public ServiceStateTracker mSST;
    private ArrayList <MmiCode> mPendingMMIs = new ArrayList<MmiCode>();
    private final Deque<MmiCode> mMMIQueue = new ArrayDeque<MmiCode>(USSD_MAX_QUEUE);
    private IccPhoneBookInterfaceManager mIccPhoneBookIntManager;
    private DeviceStateMonitor mDeviceStateMonitor;

@@ -1176,16 +1176,6 @@ public class GsmCdmaPhone extends Phone {
        return shouldConfirmCall;
    }

    private synchronized boolean addToMMIQueue(MmiCode mmi) {
        if (mPendingMMIs.size() >= 1) {
            mMMIQueue.offerLast(mmi);
            return true;
        }
        mPendingMMIs.add(mmi);
        mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
        return false;
    }

    @Override
    protected Connection dialInternal(String dialString, UUSInfo uusInfo, int videoState,
                                      Bundle intentExtras)
@@ -1210,35 +1200,23 @@ public class GsmCdmaPhone extends Phone {
            String networkPortion = PhoneNumberUtils.extractNetworkPortionAlt(newDialString);
            GsmMmiCode mmi = GsmMmiCode.newFromDialString(networkPortion, this,
                    mUiccApplication.get(), wrappedCallback);
            if (DBG) logd("dialing w/ mmi '" + mmi + "'...");
            if (DBG) logd("dialInternal: dialing w/ mmi '" + mmi + "'...");

            if (mmi == null) {
                return mCT.dial(newDialString, uusInfo, intentExtras);
            } else if (mmi.isTemporaryModeCLIR()) {
                return mCT.dial(mmi.mDialingNumber, mmi.getCLIRMode(), uusInfo, intentExtras);
            } else {
                return dialInternal(mmi);
                mPendingMMIs.add(mmi);
                mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
                mmi.processCode();
                return null;
            }
        } else {
            return mCT.dial(newDialString);
        }
    }

    protected Connection dialInternal(MmiCode mmi) {
        if (addToMMIQueue(mmi)) {
            return null;
        }
        try {
            mmi.processCode();
        } catch (CallStateException e) {
            //do nothing
        }

        // FIXME should this return null or something else?
        return null;
    }


   @Override
    public boolean handlePinMmi(String dialString) {
        MmiCode mmi;
@@ -1263,10 +1241,6 @@ public class GsmCdmaPhone extends Phone {
        return false;
    }

    private synchronized boolean isMmiQueueFull() {
        return (mMMIQueue.size() >= USSD_MAX_QUEUE - 1);
    }

    private void sendUssdResponse(String ussdRequest, CharSequence message, int returnCode,
                                   ResultReceiver wrappedCallback) {
        UssdResponse response = new UssdResponse(ussdRequest, message);
@@ -1277,16 +1251,37 @@ public class GsmCdmaPhone extends Phone {

    @Override
    public boolean handleUssdRequest(String ussdRequest, ResultReceiver wrappedCallback) {
        if (!isPhoneTypeGsm() || isMmiQueueFull()) {
        if (!isPhoneTypeGsm() || mPendingMMIs.size() > 0) {
            //todo: replace the generic failure with specific error code.
            sendUssdResponse(ussdRequest, null, TelephonyManager.USSD_RETURN_FAILURE,
                    wrappedCallback );
            return true;
        }

        // Try over IMS if possible.
        Phone imsPhone = mImsPhone;
        if ((imsPhone != null)
                && ((imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE)
                || imsPhone.isUtEnabled())) {
            try {
                logd("handleUssdRequest: attempting over IMS");
                return imsPhone.handleUssdRequest(ussdRequest, wrappedCallback);
            } catch (CallStateException cse) {
                if (!CS_FALLBACK.equals(cse.getMessage())) {
                    return false;
                }
                // At this point we've tried over IMS but have been informed we need to handover
                // back to GSM.
                logd("handleUssdRequest: fallback to CS required");
            }
        }

        // Try USSD over GSM.
        try {
            dialInternal(ussdRequest, null, VideoProfile.STATE_AUDIO_ONLY, null, wrappedCallback);
            dialInternal(ussdRequest, null, VideoProfile.STATE_AUDIO_ONLY, null,
                    wrappedCallback);
        } catch (Exception e) {
            logd("exception" + e);
            logd("handleUssdRequest: exception" + e);
            return false;
        }
        return true;
@@ -1934,19 +1929,22 @@ public class GsmCdmaPhone extends Phone {
         * The exception is cancellation of an incoming USSD-REQUEST, which is
         * not on the list.
         */
        logd("USSD Response:" + mmi);
        if (mPendingMMIs.remove(mmi) || (isPhoneTypeGsm() && (mmi.isUssdRequest() ||
                ((GsmMmiCode)mmi).isSsInfo()))) {

            ResultReceiver receiverCallback = mmi.getUssdCallbackReceiver();
            if (receiverCallback != null) {
                Rlog.i(LOG_TAG, "onMMIDone: invoking callback: " + mmi);
                int returnCode = (mmi.getState() ==  MmiCode.State.COMPLETE) ?
                    TelephonyManager.USSD_RETURN_SUCCESS : TelephonyManager.USSD_RETURN_FAILURE;
                sendUssdResponse(mmi.getDialString(), mmi.getMessage(), returnCode,
                        receiverCallback );
            } else {
                Rlog.i(LOG_TAG, "onMMIDone: notifying registrants: " + mmi);
                mMmiCompleteRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
            }
        } else {
            Rlog.i(LOG_TAG, "onMMIDone: invalid response or already handled; ignoring: " + mmi);
        }
    }

@@ -2020,15 +2018,6 @@ public class GsmCdmaPhone extends Phone {
                                                   GsmCdmaPhone.this,
                                                   mUiccApplication.get());
            onNetworkInitiatedUssd(mmi);
        } else {
            if (mMMIQueue.peek() != null) {
                try {

                    dialInternal(mMMIQueue.remove());
                } catch (Exception e) {
                    logd("Exception:" + e);
                }
            }
        }
    }

+6 −0
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ import com.android.ims.ImsConfig;
import com.android.ims.ImsManager;
import com.android.internal.R;
import com.android.internal.telephony.dataconnection.DcTracker;
import com.android.internal.telephony.imsphone.ImsPhone;
import com.android.internal.telephony.imsphone.ImsPhoneCall;
import com.android.internal.telephony.test.SimulatedRadioControl;
import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
@@ -278,6 +279,11 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
    protected TelephonyComponentFactory mTelephonyComponentFactory;

    //IMS
    /**
     * {@link CallStateException} message text used to indicate that an IMS call has failed because
     * it needs to be retried using GSM or CDMA (e.g. CS fallback).
     * TODO: Replace this with a proper exception; {@link CallStateException} doesn't make sense.
     */
    public static final String CS_FALLBACK = "cs_fallback";
    public static final String EXTRA_KEY_ALERT_TITLE = "alertTitle";
    public static final String EXTRA_KEY_ALERT_MESSAGE = "alertMessage";
+2 −15
Original line number Diff line number Diff line
@@ -16,32 +16,18 @@

package com.android.internal.telephony;

import android.content.Context;
import android.net.LinkProperties;
import android.net.NetworkCapabilities;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.WorkSource;
import android.os.ResultReceiver;
import android.telephony.CellInfo;
import android.telephony.CellLocation;
import android.telephony.CarrierConfigManager;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;

import com.android.internal.telephony.imsphone.ImsPhone;
import com.android.internal.telephony.RadioCapability;
import com.android.internal.telephony.test.SimulatedRadioControl;
import com.android.internal.telephony.uicc.IsimRecords;
import com.android.internal.telephony.uicc.UiccCard;
import com.android.internal.telephony.uicc.UsimServiceTable;

import com.android.internal.telephony.PhoneConstants.*; // ????

import java.util.List;
import java.util.Locale;

/**
 * Internal interface used to control the phone; SDK developers cannot
@@ -456,7 +442,8 @@ public interface PhoneInternalInterface {
     * @param ussdRequest the USSD command to be executed.
     * @param wrappedCallback receives the callback result.
     */
    boolean handleUssdRequest(String ussdRequest, ResultReceiver wrappedCallback);
    boolean handleUssdRequest(String ussdRequest, ResultReceiver wrappedCallback)
            throws CallStateException;

    /**
     * Handles in-call MMI commands. While in a call, or while receiving a
+5 −2
Original line number Diff line number Diff line
@@ -1629,8 +1629,11 @@ public final class GsmMmiCode extends Handler implements MmiCode {
        if (mSib != null) sb.append(" sib=" + Rlog.pii(LOG_TAG, mSib));
        if (mSic != null) sb.append(" sic=" + Rlog.pii(LOG_TAG, mSic));
        if (mPoundString != null) sb.append(" poundString=" + Rlog.pii(LOG_TAG, mPoundString));
        if (mDialingNumber != null) sb.append(" dialingNumber=" + mDialingNumber);
        if (mPwd != null) sb.append(" pwd=" + mPwd);
        if (mDialingNumber != null) {
            sb.append(" dialingNumber=" + Rlog.pii(LOG_TAG, mDialingNumber));
        }
        if (mPwd != null) sb.append(" pwd=" + Rlog.pii(LOG_TAG, mPwd));
        if (mCallbackReceiver != null) sb.append(" hasReceiver");
        sb.append("}");
        return sb.toString();
    }
+36 −45
Original line number Diff line number Diff line
@@ -137,9 +137,6 @@ public class ImsPhone extends ImsPhoneBase {
    ImsPhoneCallTracker mCT;
    ImsExternalCallTracker mExternalCallTracker;
    private ArrayList <ImsPhoneMmiCode> mPendingMMIs = new ArrayList<ImsPhoneMmiCode>();
    private final Deque<ImsPhoneMmiCode> mMMIQueue =
            new ArrayDeque<ImsPhoneMmiCode>(USSD_MAX_QUEUE);

    private ServiceState mSS = new ServiceState();

    // To redial silently through GSM or CDMA when dialing through IMS fails
@@ -373,10 +370,6 @@ public class ImsPhone extends ImsPhoneBase {
        return true;
    }

    private synchronized boolean isMmiQueueFull() {
        return (mMMIQueue.size() >= USSD_MAX_QUEUE - 1);
    }

    private void sendUssdResponse(String ussdRequest, CharSequence message, int returnCode,
                                   ResultReceiver wrappedCallback) {
        UssdResponse response = new UssdResponse(ussdRequest, message);
@@ -387,17 +380,29 @@ public class ImsPhone extends ImsPhoneBase {
    }

    @Override
    public boolean handleUssdRequest(String ussdRequest, ResultReceiver wrappedCallback) {
        if (isMmiQueueFull()) {
            //todo: replace the generic failure with specific error code.
    public boolean handleUssdRequest(String ussdRequest, ResultReceiver wrappedCallback)
            throws CallStateException {
        if (mPendingMMIs.size() > 0) {
            // There are MMI codes in progress; fail attempt now.
            Rlog.i(LOG_TAG, "handleUssdRequest: queue full: " + Rlog.pii(LOG_TAG, ussdRequest));
            sendUssdResponse(ussdRequest, null, TelephonyManager.USSD_RETURN_FAILURE,
                    wrappedCallback );
            return true;
        }
        try {
            dialInternal(ussdRequest, VideoProfile.STATE_AUDIO_ONLY, null, wrappedCallback);
        } catch (CallStateException cse) {
            if (CS_FALLBACK.equals(cse.getMessage())) {
                throw cse;
            } else {
                Rlog.w(LOG_TAG, "Could not execute USSD " + cse);
                sendUssdResponse(ussdRequest, null, TelephonyManager.USSD_RETURN_FAILURE,
                        wrappedCallback);
            }
        } catch (Exception e) {
            Rlog.d(LOG_TAG, "exception" + e);
            Rlog.w(LOG_TAG, "Could not execute USSD " + e);
            sendUssdResponse(ussdRequest, null, TelephonyManager.USSD_RETURN_FAILURE,
                    wrappedCallback);
            return false;
        }
        return true;
@@ -578,16 +583,6 @@ public class ImsPhone extends ImsPhoneBase {
        mDefaultPhone.notifyForVideoCapabilityChanged(isVideoCapable);
    }

    protected synchronized boolean addToMMIQueue(ImsPhoneMmiCode mmi) {
        if (mPendingMMIs.size() >= 1) {
            mMMIQueue.offerLast(mmi);
            return true;
        }
        mPendingMMIs.add(mmi);
        mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
        return false;
    }

    @Override
    public Connection
    dial(String dialString, int videoState) throws CallStateException {
@@ -625,9 +620,9 @@ public class ImsPhone extends ImsPhoneBase {
        // Only look at the Network portion for mmi
        String networkPortion = PhoneNumberUtils.extractNetworkPortionAlt(newDialString);
        ImsPhoneMmiCode mmi =
                ImsPhoneMmiCode.newFromDialString(networkPortion, this);
                ImsPhoneMmiCode.newFromDialString(networkPortion, this, wrappedCallback);
        if (DBG) Rlog.d(LOG_TAG,
                "dialing w/ mmi '" + mmi + "'...");
                "dialInternal: dialing w/ mmi '" + mmi + "'...");

        if (mmi == null) {
            return mCT.dial(dialString, videoState, intentExtras);
@@ -636,25 +631,30 @@ public class ImsPhone extends ImsPhoneBase {
        } else if (!mmi.isSupportedOverImsPhone()) {
            // If the mmi is not supported by IMS service,
            // try to initiate dialing with default phone
            // Note: This code is never reached; there is a bug in isSupportedOverImsPhone which
            // causes it to return true even though the "processCode" method ultimately throws the
            // exception.
            Rlog.i(LOG_TAG, "dialInternal: USSD not supported by IMS; fallback to CS.");
            throw new CallStateException(CS_FALLBACK);
        } else {
            return dialInternal(mmi);
        }
    }
            mPendingMMIs.add(mmi);
            mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));

    protected Connection dialInternal(ImsPhoneMmiCode mmi) {
        if (addToMMIQueue(mmi)) {
            return null;
        }
            try {
                mmi.processCode();
        } catch (CallStateException e) {
            //do nothing
            } catch (CallStateException cse) {
                if (CS_FALLBACK.equals(cse.getMessage())) {
                    Rlog.i(LOG_TAG, "dialInternal: fallback to GSM required.");
                    // Make sure we remove from the list of pending MMIs since it will handover to
                    // GSM.
                    mPendingMMIs.remove(mmi);
                    throw cse;
                }
            }

        // FIXME should this return null or something else?
            return null;
        }
    }

    @Override
    public void
@@ -1085,15 +1085,6 @@ public class ImsPhone extends ImsPhoneBase {
                        isUssdRequest,
                        this);
                onNetworkInitiatedUssd(mmi);
        } else {
            if (mMMIQueue.peek() != null) {
                try {

                    dialInternal(mMMIQueue.remove());
                } catch (Exception e) {
                    Rlog.d(LOG_TAG,"Exception:" + e);
                }
            }
        }
    }

Loading