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

Commit 16b58d13 authored by pkanwar's avatar pkanwar
Browse files

Provide an API to make USSD calls and read the responses.

Test: will be added in a subsequent CL.
Bug: 30973910
Change-Id: I0d826eaadd1bd5a0c23cfad651c0423f7b7cc5f6
parent c61514fb
Loading
Loading
Loading
Loading
+35 −3
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.os.PersistableBundle;
import android.os.PowerManager;
import android.os.Registrant;
import android.os.RegistrantList;
import android.os.ResultReceiver;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.WorkSource;
@@ -46,6 +47,7 @@ import android.telephony.PhoneNumberUtils;
import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.UssdResponse;

import android.telephony.cdma.CdmaCellLocation;
import android.text.TextUtils;
@@ -133,6 +135,7 @@ public class GsmCdmaPhone extends Phone {
    private String mMeid;
    // string to define how the carrier specifies its own ota sp number
    private String mCarrierOtaSpNumSchema;

    // A runnable which is used to automatically exit from Ecm after a period of time.
    private Runnable mExitEcmRunnable = new Runnable() {
        @Override
@@ -1135,6 +1138,12 @@ public class GsmCdmaPhone extends Phone {
    protected Connection dialInternal(String dialString, UUSInfo uusInfo, int videoState,
                                      Bundle intentExtras)
            throws CallStateException {
        return dialInternal(dialString, uusInfo, videoState, intentExtras, null);
    }

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

        // Need to make sure dialString gets parsed properly
        String newDialString = PhoneNumberUtils.stripSeparators(dialString);
@@ -1147,8 +1156,8 @@ public class GsmCdmaPhone extends Phone {

            // Only look at the Network portion for mmi
            String networkPortion = PhoneNumberUtils.extractNetworkPortionAlt(newDialString);
            GsmMmiCode mmi =
                    GsmMmiCode.newFromDialString(networkPortion, this, mUiccApplication.get());
            GsmMmiCode mmi = GsmMmiCode.newFromDialString(networkPortion, this,
                                                          mUiccApplication.get(), wrappedCallback);
            if (DBG) logd("dialing w/ mmi '" + mmi + "'...");

            if (mmi == null) {
@@ -1196,6 +1205,17 @@ public class GsmCdmaPhone extends Phone {
        return false;
    }

    @Override
    public boolean handleUssdRequest(String ussdRequest, ResultReceiver wrappedCallback) {
        try {
            dialInternal(ussdRequest, null, VideoProfile.STATE_AUDIO_ONLY, null, wrappedCallback);
            return true;
         } catch (Exception e) {
           logd("exception" + e);
           return false;
         }
    }

    @Override
    public void sendUssdResponse(String ussdMessge) {
        if (isPhoneTypeGsm()) {
@@ -1843,11 +1863,23 @@ 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) {
                UssdResponse response = new UssdResponse(mmi.getDialString(), mmi.getMessage());
                Bundle returnData = new Bundle();
                returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response);
                int returnCode = (mmi.getState() ==  MmiCode.State.COMPLETE) ?
                    TelephonyManager.USSD_RETURN_SUCCESS : TelephonyManager.USSD_RETURN_FAILURE;
                receiverCallback.send(returnCode, returnData);
            } else {
                mMmiCompleteRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
            }
        }
    }

    private void onNetworkInitiatedUssd(MmiCode mmi) {
        mMmiCompleteRegistrants.notifyRegistrants(
+11 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.internal.telephony;

import android.os.ResultReceiver;

/**
 * {@hide}
 */
@@ -75,4 +77,13 @@ public interface MmiCode
     */
    void processCode() throws CallStateException;

    /**
     * @return the Receiver for the Ussd Callback.
     */
    public ResultReceiver getUssdCallbackReceiver();

    /**
     * @return the dialString.
     */
    public String getDialString();
}
+9 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ 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;
@@ -449,6 +450,14 @@ public interface PhoneInternalInterface {
     */
    boolean handlePinMmi(String dialString);

    /**
     * Handles USSD commands
     *
     * @param ussdRequest the USSD command to be executed.
     * @param wrappedCallback receives the callback result.
     */
    boolean handleUssdRequest(String ussdRequest, ResultReceiver wrappedCallback);

    /**
     * Handles in-call MMI commands. While in a call, or while receiving a
     * call, use this to execute MMI commands.
+10 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import com.android.internal.telephony.Phone;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.os.ResultReceiver;
import android.telephony.Rlog;

import java.util.regex.Pattern;
@@ -207,6 +208,11 @@ public final class CdmaMmiCode extends Handler implements MmiCode {
        return false;
    }

    @Override
    public String getDialString() {
        return null;
    }

    /** Process a MMI PUK code */
    public void
    processCode() {
@@ -368,4 +374,8 @@ public final class CdmaMmiCode extends Handler implements MmiCode {
        mPhone.onMMIDone(this);
    }

    @Override
    public ResultReceiver getUssdCallbackReceiver() {
        return null;
    }
}
+17 −3
Original line number Diff line number Diff line
@@ -136,6 +136,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
    State mState = State.PENDING;
    CharSequence mMessage;
    private boolean mIsSsInfo = false;
    private ResultReceiver mCallbackReceiver;


    //***** Class Variables
@@ -183,9 +184,13 @@ public final class GsmMmiCode extends Handler implements MmiCode {
     *
     * Please see flow chart in TS 22.030 6.5.3.2
     */
    public static GsmMmiCode newFromDialString(String dialString, GsmCdmaPhone phone,
            UiccCardApplication app) {
        return newFromDialString(dialString, phone, app, null);
    }

    public static GsmMmiCode
    newFromDialString(String dialString, GsmCdmaPhone phone, UiccCardApplication app) {
    public static GsmMmiCode newFromDialString(String dialString, GsmCdmaPhone phone,
            UiccCardApplication app, ResultReceiver wrappedCallback) {
        Matcher m;
        GsmMmiCode ret = null;

@@ -202,6 +207,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
            ret.mSic = makeEmptyNull(m.group(MATCH_GROUP_SIC));
            ret.mPwd = makeEmptyNull(m.group(MATCH_GROUP_PWD_CONFIRM));
            ret.mDialingNumber = makeEmptyNull(m.group(MATCH_GROUP_DIALING_NUMBER));
            ret.mCallbackReceiver = wrappedCallback;
            // According to TS 22.030 6.5.2 "Structure of the MMI",
            // the dialing number should not ending with #.
            // The dialing number ending # is treated as unique USSD,
@@ -624,6 +630,11 @@ public final class GsmMmiCode extends Handler implements MmiCode {

    }

    @Override
    public String getDialString() {
        return mPoundString;
    }

    static private boolean
    isTwoDigitShortCode(Context context, String dialString) {
        Rlog.d(LOG_TAG, "isTwoDigitShortCode");
@@ -1062,7 +1073,6 @@ public final class GsmMmiCode extends Handler implements MmiCode {
        // response does not complete this MMI code...we wait for
        // an unsolicited USSD "Notify" or "Request".
        // The matching up of this is done in GsmCdmaPhone.

        mPhone.mCi.sendUSSD(ussdMessage,
            obtainMessage(EVENT_USSD_COMPLETE, this));
    }
@@ -1587,6 +1597,10 @@ public final class GsmMmiCode extends Handler implements MmiCode {
        return sb;
    }

    public ResultReceiver getUssdCallbackReceiver() {
        return this.mCallbackReceiver;
    }

    /***
     * TODO: It would be nice to have a method here that can take in a dialstring and
     * figure out if there is an MMI code embedded within it.  This code would replace
Loading