diff --git a/src/com/android/phone/CallForwardEditPreference.java b/src/com/android/phone/CallForwardEditPreference.java
index bdffb26..76f17b1 100644
--- a/src/com/android/phone/CallForwardEditPreference.java
+++ b/src/com/android/phone/CallForwardEditPreference.java
@@ -27,6 +27,8 @@
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.Phone;
 
+import java.util.HashMap;
+
 public class CallForwardEditPreference extends EditPhoneNumberPreference {
     private static final String LOG_TAG = "CallForwardEditPreference";
 
@@ -48,6 +50,14 @@
     private TimeConsumingPreferenceListener mTcpListener;
     // Should we replace CF queries containing an invalid number with "Voicemail"
     private boolean mReplaceInvalidCFNumber = false;
+    private boolean mCallForwardByUssd = false;
+    private CarrierXmlParser mCarrierXmlParser;
+    private int mPreviousCommand = MyHandler.MESSAGE_GET_CF;
+    private Object mCommandException;
+    private CarrierXmlParser.SsEntry.SSAction mSsAction =
+            CarrierXmlParser.SsEntry.SSAction.UNKNOWN;
+    private int mAction;
+    private HashMap<String, String> mCfInfo;
 
     public CallForwardEditPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -70,10 +80,21 @@
     }
 
     void init(TimeConsumingPreferenceListener listener, Phone phone,
-            boolean replaceInvalidCFNumber) {
+            boolean replaceInvalidCFNumber, boolean callForwardByUssd) {
         mPhone = phone;
         mTcpListener = listener;
         mReplaceInvalidCFNumber = replaceInvalidCFNumber;
+        mCallForwardByUssd = callForwardByUssd;
+        Log.d(LOG_TAG,
+                "init :mReplaceInvalidCFNumber " + mReplaceInvalidCFNumber + ", mCallForwardByUssd "
+                        + mCallForwardByUssd);
+        if (mCallForwardByUssd) {
+            mCfInfo = new HashMap<String, String>();
+            TelephonyManager telephonyManager = new TelephonyManager(getContext(),
+                    phone.getSubId());
+            mCarrierXmlParser = new CarrierXmlParser(getContext(),
+                    telephonyManager.getSimCarrierId());
+        }
     }
 
     void restoreCallForwardInfo(CallForwardInfo cf) {
@@ -132,17 +153,26 @@
                 // Display no forwarding number while we're waiting for
                 // confirmation
                 setSummaryOn("");
-
-                // the interface of Phone.setCallForwardingOption has error:
-                // should be action, reason...
-                mPhone.setCallForwardingOption(action,
-                        reason,
-                        number,
-                        time,
-                        mHandler.obtainMessage(MyHandler.MESSAGE_SET_CF,
-                                action,
-                                MyHandler.MESSAGE_SET_CF));
-
+                if (!mCallForwardByUssd) {
+                    // the interface of Phone.setCallForwardingOption has error:
+                    // should be action, reason...
+                    mPhone.setCallForwardingOption(action,
+                            reason,
+                            number,
+                            time,
+                            mHandler.obtainMessage(MyHandler.MESSAGE_SET_CF,
+                                    action,
+                                    MyHandler.MESSAGE_SET_CF));
+                } else {
+                    if (action == CommandsInterface.CF_ACTION_REGISTRATION) {
+                        mCfInfo.put(CarrierXmlParser.TAG_ENTRY_NUMBER, number);
+                        mCfInfo.put(CarrierXmlParser.TAG_ENTRY_TIME, Integer.toString(time));
+                    } else {
+                        mCfInfo.clear();
+                    }
+                    mHandler.sendMessage(mHandler.obtainMessage(mHandler.MESSAGE_SET_CF_USSD,
+                            action, MyHandler.MESSAGE_SET_CF));
+                }
                 if (mTcpListener != null) {
                     mTcpListener.onStarted(this, false);
                 }
@@ -185,11 +215,17 @@
      * {@link TimeConsumingPreferenceListener#onError} if an error has occurred.
      */
     void startCallForwardOptionsQuery() {
-        mPhone.getCallForwardingOption(reason,
-                mHandler.obtainMessage(MyHandler.MESSAGE_GET_CF,
-                        // unused in this case
-                        CommandsInterface.CF_ACTION_DISABLE,
-                        MyHandler.MESSAGE_GET_CF, null));
+        if (!mCallForwardByUssd) {
+            mPhone.getCallForwardingOption(reason,
+                    mHandler.obtainMessage(MyHandler.MESSAGE_GET_CF,
+                            // unused in this case
+                            CommandsInterface.CF_ACTION_DISABLE,
+                            MyHandler.MESSAGE_GET_CF, null));
+        } else {
+            mHandler.sendMessage(mHandler.obtainMessage(mHandler.MESSAGE_GET_CF_USSD,
+                    // unused in this case
+                    CommandsInterface.CF_ACTION_DISABLE, MyHandler.MESSAGE_GET_CF, null));
+        }
         if (mTcpListener != null) {
             mTcpListener.onStarted(this, true);
         }
@@ -238,6 +274,47 @@
     private class MyHandler extends Handler {
         static final int MESSAGE_GET_CF = 0;
         static final int MESSAGE_SET_CF = 1;
+        static final int MESSAGE_GET_CF_USSD = 2;
+        static final int MESSAGE_SET_CF_USSD = 3;
+
+        TelephonyManager.UssdResponseCallback mUssdCallback =
+                new TelephonyManager.UssdResponseCallback() {
+                    @Override
+                    public void onReceiveUssdResponse(final TelephonyManager telephonyManager,
+                            String request, CharSequence response) {
+                        if (mSsAction == CarrierXmlParser.SsEntry.SSAction.UNKNOWN) {
+                            return;
+                        }
+
+                        HashMap<String, String> analysisResult = mCarrierXmlParser.getFeature(
+                                CarrierXmlParser.FEATURE_CALL_FORWARDING)
+                                .getResponseSet(mSsAction,
+                                        response.toString());
+
+                        Throwable throwableException = null;
+                        if (analysisResult.get(CarrierXmlParser.TAG_RESPONSE_STATUS_ERROR)
+                                != null) {
+                            throwableException = new CommandException(
+                                    CommandException.Error.GENERIC_FAILURE);
+                        }
+
+                        Object obj = null;
+                        if (mSsAction == CarrierXmlParser.SsEntry.SSAction.QUERY) {
+                            obj = makeCallForwardInfo(analysisResult);
+                        }
+
+                        sendCfMessage(obj, throwableException);
+                    }
+
+                    @Override
+                    public void onReceiveUssdResponseFailed(final TelephonyManager telephonyManager,
+                            String request, int failureCode) {
+                        Log.d(LOG_TAG, "receive the ussd result failed");
+                        Throwable throwableException = new CommandException(
+                                CommandException.Error.GENERIC_FAILURE);
+                        sendCfMessage(null, throwableException);
+                    }
+                };
 
         @Override
         public void handleMessage(Message msg) {
@@ -248,6 +325,12 @@
                 case MESSAGE_SET_CF:
                     handleSetCFResponse(msg);
                     break;
+                case MESSAGE_GET_CF_USSD:
+                    prepareUssdCommand(msg, CarrierXmlParser.SsEntry.SSAction.QUERY);
+                    break;
+                case MESSAGE_SET_CF_USSD:
+                    prepareUssdCommand(msg, CarrierXmlParser.SsEntry.SSAction.UNKNOWN);
+                    break;
             }
         }
 
@@ -334,14 +417,116 @@
 
         private void handleSetCFResponse(Message msg) {
             AsyncResult ar = (AsyncResult) msg.obj;
-
             if (ar.exception != null) {
                 Log.d(LOG_TAG, "handleSetCFResponse: ar.exception=" + ar.exception);
                 // setEnabled(false);
             }
             Log.d(LOG_TAG, "handleSetCFResponse: re get");
-            mPhone.getCallForwardingOption(reason,
-                    obtainMessage(MESSAGE_GET_CF, msg.arg1, MESSAGE_SET_CF, ar.exception));
+            if (!mCallForwardByUssd) {
+                mPhone.getCallForwardingOption(reason,
+                        obtainMessage(MESSAGE_GET_CF, msg.arg1, MESSAGE_SET_CF, ar.exception));
+            } else {
+                mHandler.sendMessage(mHandler.obtainMessage(mHandler.MESSAGE_GET_CF_USSD,
+                        msg.arg1, MyHandler.MESSAGE_SET_CF, ar.exception));
+            }
+        }
+
+        private void prepareUssdCommand(Message msg,
+                CarrierXmlParser.SsEntry.SSAction inputSsAction) {
+            mAction = msg.arg1;
+            mPreviousCommand = msg.arg2;
+            mCommandException = msg.obj;
+            mSsAction = inputSsAction;
+
+            if (mSsAction != CarrierXmlParser.SsEntry.SSAction.QUERY) {
+                if (mAction == CommandsInterface.CF_ACTION_REGISTRATION) {
+                    mSsAction = CarrierXmlParser.SsEntry.SSAction.UPDATE_ACTIVATE;
+                } else {
+                    mSsAction = CarrierXmlParser.SsEntry.SSAction.UPDATE_DEACTIVATE;
+                }
+            }
+
+            new Thread(new Runnable() {
+                @Override
+                public void run() {
+                    sendUssdCommand(mUssdCallback, mSsAction, mCfInfo.isEmpty() ? null : mCfInfo);
+                }
+            }).start();
+        }
+
+        private void sendUssdCommand(TelephonyManager.UssdResponseCallback inputCallback,
+                CarrierXmlParser.SsEntry.SSAction inputAction,
+                HashMap<String, String> inputCfInfo) {
+            String newUssdCommand = mCarrierXmlParser.getFeature(
+                    CarrierXmlParser.FEATURE_CALL_FORWARDING)
+                    .makeCommand(inputAction, inputCfInfo);
+            TelephonyManager telephonyManager =
+                    (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
+            telephonyManager.sendUssdRequest(newUssdCommand, inputCallback, mHandler);
+        }
+
+        private Message makeGetCfMessage(int inputMsgWhat, int inputMsgArg2, Object inputMsgObj) {
+            return mHandler.obtainMessage(inputMsgWhat,
+                    mAction,
+                    inputMsgArg2,
+                    inputMsgObj);
+        }
+
+        private Message makeSetCfMessage(int inputMsgWhat, int inputMsgArg2) {
+            return mHandler.obtainMessage(inputMsgWhat,
+                    mAction,
+                    inputMsgArg2);
+        }
+
+        private void sendCfMessage(Object inputArObj, Throwable inputThrowableException) {
+            Message message;
+            if (mSsAction == CarrierXmlParser.SsEntry.SSAction.UNKNOWN) {
+                return;
+            }
+            if (mSsAction == CarrierXmlParser.SsEntry.SSAction.QUERY) {
+                message = makeGetCfMessage(MyHandler.MESSAGE_GET_CF, mPreviousCommand,
+                        mCommandException);
+            } else {
+                message = makeSetCfMessage(MyHandler.MESSAGE_SET_CF, MyHandler.MESSAGE_SET_CF);
+            }
+            AsyncResult.forMessage(message, inputArObj, inputThrowableException);
+            message.sendToTarget();
+        }
+
+        private CallForwardInfo[] makeCallForwardInfo(HashMap<String, String> inputInfo) {
+            int tmpStatus = 0;
+            String tmpNumberStr = "";
+            int tmpTime = 0;
+            if (inputInfo != null && inputInfo.size() != 0) {
+                String tmpStatusStr = inputInfo.get(CarrierXmlParser.TAG_RESPONSE_STATUS);
+
+                String tmpTimeStr = inputInfo.get(CarrierXmlParser.TAG_RESPONSE_TIME);
+                if (!TextUtils.isEmpty(tmpStatusStr)) {
+                    if (tmpStatusStr.equals(
+                            CarrierXmlParser.TAG_COMMAND_RESULT_DEFINITION_ACTIVATE)) {
+                        tmpStatus = 1;
+                    } else if (tmpStatusStr.equals(
+                            CarrierXmlParser.TAG_COMMAND_RESULT_DEFINITION_DEACTIVATE)
+                            || tmpStatusStr.equals(
+                            CarrierXmlParser.TAG_COMMAND_RESULT_DEFINITION_UNREGISTER)) {
+                        tmpStatus = 0;
+                    }
+                }
+
+                tmpNumberStr = inputInfo.get(CarrierXmlParser.TAG_RESPONSE_NUMBER);
+                if (!TextUtils.isEmpty(tmpTimeStr)) {
+                    tmpTime = Integer.valueOf(inputInfo.get(CarrierXmlParser.TAG_RESPONSE_TIME));
+                }
+            }
+
+            CallForwardInfo[] newCallForwardInfo = new CallForwardInfo[1];
+            newCallForwardInfo[0] = new CallForwardInfo();
+            newCallForwardInfo[0].status = tmpStatus;
+            newCallForwardInfo[0].reason = reason;
+            newCallForwardInfo[0].serviceClass = mServiceClass;
+            newCallForwardInfo[0].number = tmpNumberStr;
+            newCallForwardInfo[0].timeSeconds = tmpTime;
+            return newCallForwardInfo;
         }
     }
 
diff --git a/src/com/android/phone/CarrierXmlParser.java b/src/com/android/phone/CarrierXmlParser.java
new file mode 100644
index 0000000..2497348
--- /dev/null
+++ b/src/com/android/phone/CarrierXmlParser.java
@@ -0,0 +1,674 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone;
+
+import android.content.Context;
+import android.content.res.XmlResourceParser;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * CarrierXmlParser is a xml parser. It parses the carrier's ussd format from carrier_ss_string.xml.
+ * The carrier_ss_string.xml defines carrier's ussd structure and meaning in res/xml folder.
+ * Some carrier has specific ussd structure ,developer can add new xml and xml is named
+ * carrier_ss_string_carrierId.xml. The carrierId is a number and is defined in
+ * <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/carrier_list.textpb">here</a>
+ * For example: carrier_ss_string_850.xml
+ * <p>
+ * How do use CarrierXmlParser?
+ * For example:
+ * @see CallForwardEditPreference
+ *     TelephonyManager telephonyManager = new TelephonyManager(getContext(),phone.getSubId());
+ *     CarrierXmlParser  = new CarrierXmlParser(getContext(), telephonyManager.getSimCarrierId());
+ *
+ *     //make a ussd command
+ *     String newUssdCommand = mCarrierXmlParser.getFeature(
+ *             CarrierXmlParser.FEATURE_CALL_FORWARDING).makeCommand(inputAction, inputCfInfo);
+ *     //analyze ussd result
+ *     HashMap<String, String> analysisResult = mCarrierXmlParser.getFeature(
+ *             CarrierXmlParser.FEATURE_CALL_FORWARDING)
+ *             .getResponseSet(mSsAction, response.toString());
+ */
+public class CarrierXmlParser {
+    public static final String LOG_TAG = "CarrierXmlParser";
+    private static final boolean DEBUG = true;
+
+    private static final String STAR_SIGN = "*";
+    private static final String POUND_SIGN = "#";
+
+    private static final String TAG_SIGN = "tag_";
+
+    // To define feature's item name in xml
+    public static final String FEATURE_CALL_FORWARDING = "callforwarding";
+    public static final String FEATURE_CALLER_ID = "callerid";
+
+    // COMMAND_NAME is xml's command name.
+    public static final String TAG_COMMAND_NAME_QUERY = "query";
+    public static final String TAG_COMMAND_NAME_ACTIVATE = "activate";
+    public static final String TAG_COMMAND_NAME_DEACTIVATE = "deactivate";
+
+    // To define string level in xml.
+    // level 1
+    private static final String TAG_FEATURE = "feature";
+    private static final String TAG_REGULAR_PARSER = "regular_parser";
+    // level 2
+    private static final String TAG_COMMAND = "command";
+    // level 3
+    private static final String TAG_SERVICE_CODE = "service_code";
+    private static final String TAG_ACTION_CODE = "action_code";
+    private static final String TAG_PARAMETER = "parameter";
+    private static final String TAG_RESPONSE_FORMAT = "response_format";
+    private static final String TAG_COMMAND_RESULT = "command_result";
+    // level 4
+    private static final String TAG_ENTRY = "entry";
+
+    private static final String ATTR_NAME = "name";
+    private static final String ATTR_PARAMETER_NUM = "number";
+    private static final String ATTR_POSITION = "position";
+    private static final String ATTR_RESULT_KEY = "key";
+    private static final String ATTR_DEFINITION_KEY = "definition";
+
+    HashMap<String, SsFeature> mFeatureMaps;
+    private static String sParserFormat = "";
+
+    // TAG_ENTRY_NUMBER and TAG_ENTRY_TIME is xml's entry value.
+    // This is mapping user's input value. For example: number,time ...
+    // When UI makes command ,it will map the value and insert this value at position location.
+    // How to use it?
+    //      The UI calls CarrierXmlParser's makeCommand function and inputs the hashmap which
+    //      includes tag_name and user's input value.
+    //      For example: User calls CarrierXmlParser's makeCommand in call forwarding , and inputs
+    //      the hashmap {<TAG_ENTRY_NUMBER,0123456789>,<TAG_ENTRY_TIME,20>}
+    // If developer wants to add new one, xml string should the same as hashmap's name.
+    public static final String TAG_ENTRY_NUMBER = "tag_number";
+    public static final String TAG_ENTRY_TIME = "tag_time";
+
+    // "response_format" key
+    // The key of "response_format" should define as below in xml.
+    // The UI will use it to define value from the response command
+    // and use the data show the screen.
+    public static final String TAG_RESPONSE_STATUS = "status_code";
+    public static final String TAG_RESPONSE_STATUS_ERROR = "RESPONSE_ERROR";
+    public static final String TAG_RESPONSE_NUMBER = "number";
+    public static final String TAG_RESPONSE_TIME = "time";
+
+    // This is the definition for the entry's key in response_format.
+    // Xml's COMMAND_RESULT_DEFINITION should same as below.
+    public static final String TAG_COMMAND_RESULT_DEFINITION_ACTIVATE = "activate";
+    public static final String TAG_COMMAND_RESULT_DEFINITION_DEACTIVATE = "deactivate";
+    public static final String TAG_COMMAND_RESULT_DEFINITION_UNREGISTER = "unregister";
+    public static final String TAG_COMMAND_RESULT_DEFINITION_OK = "ok";
+    public static final String TAG_COMMAND_RESULT_DEFINITION_FAIL = "fail";
+
+    /**
+     * UssdParser is a string parser. It parses the USSD response message.
+     */
+    public static class UssdParser {
+        private Vector<String> mParserStr = new Vector<String>();
+        private Pattern mPatternSuppServiceResponse;
+
+        public UssdParser(String inputParserFormat) {
+            mPatternSuppServiceResponse = Pattern.compile(inputParserFormat);
+        }
+
+        /**
+         * This function is a parser and analyzes the USSD responses message.
+         *
+         * @param responseString The USSD responses message.
+         */
+        public void newFromResponseString(String responseString) {
+            Matcher m;
+            m = mPatternSuppServiceResponse.matcher(responseString);
+            if (m.matches()) {
+                mParserStr.clear();
+                int groupSize = m.groupCount();
+                for (int i = 0; i <= groupSize; i++) {
+                    if (!TextUtils.isEmpty(m.group(i))) {
+                        mParserStr.add(m.group(i));
+                    }
+                }
+            }
+        }
+
+        /**
+         * To get the UssdParser result.
+         */
+        public Vector<String> getResult() {
+            return mParserStr;
+        }
+    }
+
+    /**
+     * CarrierXmlParser parses command from xml and saves in SsEntry class.
+     */
+    public static class SsEntry {
+        public enum SSAction {
+            UNKNOWN,
+            QUERY,
+            UPDATE_ACTIVATE,
+            UPDATE_DEACTIVATE
+        }
+
+        public String serviceCode;
+        public SSAction ssAction = SSAction.UNKNOWN;
+        public String actionCode;
+        public HashMap<Integer, String> commandParameter = new HashMap<Integer, String>();
+        public HashMap<Integer, String> responseFormat = new HashMap<Integer, String>();
+
+        public SsEntry(String action) {
+            if (action.equals(TAG_COMMAND_NAME_QUERY)) {
+                ssAction = SSAction.QUERY;
+            } else if (action.equals(TAG_COMMAND_NAME_ACTIVATE)) {
+                ssAction = SSAction.UPDATE_ACTIVATE;
+            } else if (action.equals(TAG_COMMAND_NAME_DEACTIVATE)) {
+                ssAction = SSAction.UPDATE_DEACTIVATE;
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "SsEntry serviceCode:" + serviceCode
+                    + ", ssAction:" + ssAction
+                    + ", actionCode:" + actionCode
+                    + ", commandParameter:" + commandParameter.toString()
+                    + ", responseFormat:" + responseFormat.toString();
+        }
+
+        /**
+         * To get the caller id command by xml's structure.
+         */
+        public String getCommandStructure() {
+            String result = actionCode + serviceCode;
+            int mapSize = commandParameter.size();
+            int parameterIndex = 0;
+            while (parameterIndex < mapSize) {
+                parameterIndex++;
+                if (commandParameter.containsKey(parameterIndex)) {
+                    if (commandParameter.get(parameterIndex) != null) {
+                        result = result + STAR_SIGN + commandParameter.get(parameterIndex);
+                    }
+                }
+            }
+            result = result + POUND_SIGN;
+            Log.d(LOG_TAG, "getCommandStructure result:" + result);
+            return result;
+        }
+
+        /**
+         * To make ussd command by xml's structure.
+         *
+         * @param inputInformationSet This is a map which includes parameters from UI.
+         *                            The name of map is mapping parameter's key of entry in xml.
+         */
+        public String makeCommand(Map<String, String> inputInformationSet) {
+            String result = actionCode + serviceCode;
+            int mapSize = commandParameter.size();
+            int parameterIndex = 0;
+            int counter = 1;
+            Map<String, String> informationSet = inputInformationSet;
+            while (parameterIndex < mapSize) {
+                if (commandParameter.containsKey(counter)) {
+                    String getInputValue = "";
+                    // need to handle tag_XXXX
+                    if (informationSet != null && informationSet.size() > 0
+                            && informationSet.containsKey(commandParameter.get(counter))) {
+                        getInputValue = informationSet.get(commandParameter.get(counter));
+                    }
+                    if (TextUtils.isEmpty(getInputValue)) {
+                        result = result + STAR_SIGN + commandParameter.get(counter);
+                    } else {
+                        result = result + STAR_SIGN + informationSet.get(
+                                commandParameter.get(counter));
+                    }
+                    parameterIndex++;
+                } else {
+                    result = result + STAR_SIGN;
+                }
+                counter++;
+            }
+            result = result + POUND_SIGN;
+            return result;
+        }
+
+        /**
+         * To parse the specific key and value from response message.
+         *
+         * @param inputResponse  This is a ussd response message from network.
+         * @param responseDefine This is the definition for "command_result" in xml.
+         */
+        public HashMap<String, String> getResponseSet(String inputResponse,
+                HashMap<String, ArrayList<SsResultEntry>> responseDefine) {
+            HashMap<String, String> responseSet = new HashMap<String, String>();
+            if (TextUtils.isEmpty(sParserFormat)) {
+                return responseSet;
+            }
+            UssdParser parserResult = new UssdParser(sParserFormat);
+            parserResult.newFromResponseString(inputResponse);
+            if (parserResult == null) {
+                return responseSet;
+            }
+
+            Vector<String> result = parserResult.getResult();
+
+            if (result == null) {
+                return responseSet;
+            }
+            for (int i = 0; i < result.size(); i++) {
+                if (responseFormat.containsKey(i)) {
+                    String defineString = "";
+                    if (responseDefine.containsKey(responseFormat.get(i))) {
+                        for (int x = 0; x < responseDefine.get(responseFormat.get(i)).size(); x++) {
+                            defineString = ((SsResultEntry) responseDefine.get(
+                                    responseFormat.get(i)).get(x)).getDefinitionByCompareValue(
+                                    result.get(i));
+                            if (!TextUtils.isEmpty(defineString)) {
+                                break;
+                            }
+                        }
+                        // if status_code do not match definition value, we will set command error.
+                        if (TAG_RESPONSE_STATUS.equals(responseFormat.get(i))) {
+                            if (TextUtils.isEmpty(defineString)) {
+                                responseSet.put(TAG_RESPONSE_STATUS_ERROR,
+                                        TAG_RESPONSE_STATUS_ERROR);
+                            }
+                        }
+                    }
+                    if (TextUtils.isEmpty(defineString)) {
+                        responseSet.put(responseFormat.get(i), result.get(i));
+                    } else {
+                        responseSet.put(responseFormat.get(i), defineString);
+                    }
+                }
+            }
+            return responseSet;
+        }
+    }
+
+    /**
+     * CarrierXmlParser parses command_result from xml and saves in SsResultEntry class.
+     */
+    public static class SsResultEntry {
+        String mDefinition;
+        String mCompareValue;
+
+        public SsResultEntry() {
+        }
+
+        @Override
+        public String toString() {
+            return "SsResultEntry mDefinition:" + mDefinition
+                    + ", mCompareValue:" + mCompareValue;
+        }
+
+        /**
+         * If mCompareValue item is the same as compare value,it will return the mDefinition.
+         *
+         * @param inputValue This is the entry of response command's value.
+         * @return mDefinition or null.
+         */
+        public String getDefinitionByCompareValue(String inputValue) {
+            if (mCompareValue.equals(inputValue)) {
+                return mDefinition;
+            }
+            return null;
+        }
+    }
+
+    /**
+     * CarrierXmlParser parses feature from xml and saves in SsFeature class.
+     */
+    public class SsFeature {
+        public HashMap<SsEntry.SSAction, SsEntry> ssEntryHashMap =
+                new HashMap<SsEntry.SSAction, SsEntry>();
+        public HashMap<String, ArrayList<SsResultEntry>> responseCode =
+                new HashMap<String, ArrayList<SsResultEntry>>();
+
+        public SsFeature() {
+        }
+
+        private String getResponseCodeString() {
+            String result = "";
+            for (Map.Entry<String, ArrayList<SsResultEntry>> entry : responseCode.entrySet()) {
+                ArrayList<SsResultEntry> values = entry.getValue();
+                for (int i = 0; i < values.size(); i++) {
+                    result += "value of i is " + ((SsResultEntry) values.get(i)).toString();
+                }
+            }
+            return result;
+        }
+
+        @Override
+        public String toString() {
+            return getResponseCodeString();
+        }
+
+        /**
+         * To get the caller id command by xml's structure.
+         *
+         * @param inputAction This is action_code of command item from xml.
+         */
+        public String getCommandStructure(SsEntry.SSAction inputAction) {
+            SsEntry entry = ssEntryHashMap.get(inputAction);
+            return entry.getCommandStructure();
+        }
+
+        /**
+         * To make the ussd command by xml structure
+         *
+         * @param inputAction         This is action_code of command item from xml.
+         * @param inputInformationSet This is for parameter of command.
+         * @return The ussd command string.
+         */
+        public String makeCommand(SsEntry.SSAction inputAction,
+                Map<String, String> inputInformationSet) {
+            SsEntry entry = ssEntryHashMap.get(inputAction);
+            return entry.makeCommand(inputInformationSet);
+        }
+
+        /**
+         * To parse the special key and value from response message.
+         *
+         * @param inputAction   This is action_code of command item from xml.
+         * @param inputResponse This is response message from network.
+         * @return The set includes specific key and value.
+         */
+        public HashMap<String, String> getResponseSet(SsEntry.SSAction inputAction,
+                String inputResponse) {
+            SsEntry entry = ssEntryHashMap.get(inputAction);
+            return entry.getResponseSet(inputResponse, responseCode);
+        }
+    }
+
+    /**
+     * @param context context to get res's xml
+     * @param carrierId carrier id of the current subscription. The carrier ID is an Android
+     * platform-wide identifier for a carrier. AOSP maintains carrier ID assignments in
+     * <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/carrier_list.textpb">here</a>
+     */
+    public CarrierXmlParser(Context context, int carrierId) {
+        try {
+            int xmlResId = 0;
+            if (carrierId != TelephonyManager.UNKNOWN_CARRIER_ID) {
+                String xmlResIdName = "carrier_ss_string" + "_" + carrierId;
+                xmlResId = context.getResources().getIdentifier(xmlResIdName, "xml",
+                        context.getPackageName());
+            }
+            if (xmlResId == 0) {
+                xmlResId = R.xml.carrier_ss_string;
+            }
+            Log.d(LOG_TAG, "carrierId: " + carrierId);
+
+            XmlResourceParser parser = context.getResources().getXml(xmlResId);
+            mFeatureMaps = parseXml(parser);
+        } catch (Exception e) {
+            Log.d(LOG_TAG, "Error parsing XML " + e.toString());
+        }
+    }
+
+    private HashMap<String, SsFeature> parseXml(XmlResourceParser parser) throws IOException {
+        HashMap<String, SsFeature> features = new HashMap<String, SsFeature>();
+        try {
+            int eventType = parser.getEventType();
+            while (eventType != XmlPullParser.END_DOCUMENT) {
+                if (eventType == XmlPullParser.START_TAG) {
+                    if (TAG_REGULAR_PARSER.equals(parser.getName())) {
+                        sParserFormat = readText(parser);
+                        Log.d(LOG_TAG, "sParserFormat " + sParserFormat);
+                    } else if (TAG_FEATURE.equals(parser.getName())) {
+                        String featureName = getSpecificAttributeValue(parser, ATTR_NAME);
+                        if (!TextUtils.isEmpty(featureName)) {
+                            SsFeature feature = generateFeatureList(parser);
+                            features.put(featureName, feature);
+                            Log.d(LOG_TAG, "add " + featureName + " to map:" + feature.toString());
+                        }
+                    }
+                }
+                parser.next();
+                eventType = parser.getEventType();
+            }
+        } catch (XmlPullParserException e) {
+            e.printStackTrace();
+        }
+        return features;
+    }
+
+    private SsFeature generateFeatureList(XmlResourceParser parser)
+            throws XmlPullParserException, IOException {
+        SsFeature ssfeature = new SsFeature();
+        int outerDepth = parser.getDepth();
+
+        Log.d(LOG_TAG, "generateFeatureList outerDepth" + outerDepth);
+
+        while (parser.next() != XmlPullParser.END_DOCUMENT) {
+            Log.d(LOG_TAG, "generateFeatureList parser.getDepth()" + parser.getDepth());
+
+            int eventType = parser.getEventType();
+            if (eventType == XmlPullParser.END_TAG
+                    && outerDepth == parser.getDepth()) {
+                break;
+            }
+
+            if (eventType != XmlPullParser.START_TAG) {
+                continue;
+            }
+            String name = parser.getName();
+            // Starts by looking for the command tag.
+            if (TAG_COMMAND.equals(name)) {
+                SsEntry entry = readCommandEntry(parser);
+                ssfeature.ssEntryHashMap.put(entry.ssAction, entry);
+            } else if (TAG_COMMAND_RESULT.equals(name)) {
+                readCommandResultEntry(parser, ssfeature);
+            }
+        }
+        return ssfeature;
+    }
+
+    private void readCommandResultEntry(XmlResourceParser parser, SsFeature ssFeature)
+            throws XmlPullParserException, IOException {
+        while (parser.next() != XmlPullParser.END_DOCUMENT) {
+            int eventType = parser.getEventType();
+            if (eventType == XmlPullParser.END_TAG
+                    && TAG_COMMAND_RESULT.equals(parser.getName())) {
+                break;
+            }
+            if (eventType == XmlPullParser.START_TAG
+                    && TAG_ENTRY.equals(parser.getName())) {
+                String key = getSpecificAttributeValue(parser, ATTR_RESULT_KEY);
+                if (!TextUtils.isEmpty(key)) {
+                    SsResultEntry entry = new SsResultEntry();
+                    entry.mDefinition = getSpecificAttributeValue(parser, ATTR_DEFINITION_KEY);
+                    entry.mCompareValue = readText(parser);
+                    if (ssFeature.responseCode.containsKey(key)) {
+                        ssFeature.responseCode.get(key).add(entry);
+                    } else {
+                        ArrayList<SsResultEntry> arrayList = new ArrayList<>();
+                        arrayList.add(entry);
+                        ssFeature.responseCode.put(key, arrayList);
+                    }
+                }
+            }
+        }
+    }
+
+    private SsEntry readCommandEntry(XmlResourceParser parser)
+            throws XmlPullParserException, IOException {
+        int outerDepth = parser.getDepth();
+        String command_action = getSpecificAttributeValue(parser, ATTR_NAME);
+        SsEntry entry = new SsEntry(command_action);
+
+        while (parser.next() != XmlPullParser.END_DOCUMENT) {
+            int eventType = parser.getEventType();
+            if (eventType == XmlPullParser.END_TAG
+                    && outerDepth == parser.getDepth()) {
+                break;
+            }
+
+            if (eventType != XmlPullParser.START_TAG) {
+                continue;
+            }
+
+            String name = parser.getName();
+            if (TAG_SERVICE_CODE.equals(name)) {
+                entry.serviceCode = readText(parser);
+            } else if (TAG_ACTION_CODE.equals(name)) {
+                entry.actionCode = readText(parser);
+            } else if (TAG_PARAMETER.equals(name)) {
+                String number = getSpecificAttributeValue(parser, ATTR_PARAMETER_NUM);
+                if (!TextUtils.isEmpty(number)) {
+                    readParameters(parser, entry, Integer.valueOf(number), TAG_PARAMETER);
+                }
+            } else if (TAG_RESPONSE_FORMAT.equals(name)) {
+                String number = getSpecificAttributeValue(parser, ATTR_PARAMETER_NUM);
+                if (!TextUtils.isEmpty(number)) {
+                    readParameters(parser, entry, Integer.valueOf(number), TAG_RESPONSE_FORMAT);
+                }
+            }
+        }
+        Log.d(LOG_TAG, "ssEntry:" + entry.toString());
+        return entry;
+    }
+
+    private void readParameters(XmlResourceParser parser, SsEntry entry, int num, String parentTag)
+            throws IOException, XmlPullParserException {
+        Log.d(LOG_TAG, "readParameters() nume:" + num);
+        int i = 0;
+        while (i < num) {
+            if (parser.next() == XmlPullParser.START_TAG) {
+                String name = parser.getName();
+                if (TAG_ENTRY.equals(name)) {
+                    String position = getSpecificAttributeValue(parser, ATTR_POSITION);
+                    if (!TextUtils.isEmpty(position)) {
+                        if (TAG_PARAMETER.equals(parentTag)) {
+                            String value = readText(parser);
+                            if (!TextUtils.isEmpty(value)) {
+                                entry.commandParameter.put(Integer.valueOf(position), value);
+                            }
+                        } else if (TAG_RESPONSE_FORMAT.equals(parentTag)) {
+                            String key = getSpecificAttributeValue(parser, ATTR_RESULT_KEY);
+                            if (!TextUtils.isEmpty(key)) {
+                                entry.responseFormat.put(Integer.valueOf(position), key);
+                            }
+                        }
+                        i++;
+                    }
+                }
+            }
+        }
+    }
+
+    private String getSpecificAttributeValue(XmlResourceParser parser, String attrTag) {
+        String value = "";
+        for (int i = 0; i < parser.getAttributeCount(); i++) {
+            if (attrTag.equals(parser.getAttributeName(i))) {
+                value = parser.getAttributeValue(i);
+            }
+        }
+        return value;
+    }
+
+    private String readText(XmlResourceParser parser) throws IOException, XmlPullParserException {
+        String result = "";
+        if (parser.next() == XmlPullParser.TEXT) {
+            result = parser.getText();
+            parser.nextTag();
+        }
+        return result;
+    }
+
+    /**
+     * CarrierXmlParser parses the xml and saves in mFeatureMap.
+     * To use this function get feature from the mFeatureMaps.
+     *
+     * @param inputFeatureName This is feature's name from xml.
+     */
+    public SsFeature getFeature(String inputFeatureName) {
+        return mFeatureMaps.get(inputFeatureName);
+    }
+
+    /**
+     * To check the command which is dialed by user is caller id command.
+     * <p>
+     * If it is a caller id command which sets to activate, return the {@code
+     * SsEntry.SSAction.UPDATE_ACTIVATE}.
+     * If it is a caller id command which sets to deactivate, return the {@code
+     * SsEntry.SSAction.UPDATE_DEACTIVATE}.
+     * If it is not a caller id command, return the {@code SsEntry.SSAction.UNKNOWN}.
+     *
+     * @param inputCommand This is caller id's ussd command which is dialed by user.
+     * @return {@link SsEntry.SSAction}
+     */
+    public SsEntry.SSAction getCallerIdUssdCommandAction(String inputCommand) {
+        if (isCallerIdActivate(inputCommand)) {
+            return SsEntry.SSAction.UPDATE_ACTIVATE;
+        }
+        if (isCallerIdDeactivate(inputCommand)) {
+            return SsEntry.SSAction.UPDATE_DEACTIVATE;
+        }
+        return SsEntry.SSAction.UNKNOWN;
+    }
+
+    private String getCallerIdActivateCommandFromXml() {
+        return getFeature(FEATURE_CALLER_ID).getCommandStructure(SsEntry.SSAction.UPDATE_ACTIVATE);
+    }
+
+    private String getCallerIdDeactivateCommandFromXml() {
+        return getFeature(FEATURE_CALLER_ID).getCommandStructure(
+                SsEntry.SSAction.UPDATE_DEACTIVATE);
+    }
+
+    private boolean isCallerIdActivate(String inputStr) {
+        String activateStr = getCallerIdActivateCommandFromXml();
+        return compareCommand(activateStr, inputStr);
+    }
+
+    private boolean isCallerIdDeactivate(String inputStr) {
+        String activateStr = getCallerIdDeactivateCommandFromXml();
+        return compareCommand(activateStr, inputStr);
+    }
+
+    private boolean compareCommand(String activateStr, String inputStr) {
+        String[] activateArray = activateStr.split("\\" + STAR_SIGN);
+        String[] inputArray = inputStr.split("\\" + STAR_SIGN);
+
+        if (activateArray.length == 0 || inputArray.length == 0) {
+            return false;
+        }
+        for (int i = 0; i < activateArray.length; i++) {
+            if (activateArray[i].startsWith(TAG_SIGN)) {
+                continue;
+            }
+            if (!activateArray[i].equals(inputArray[i])) {
+                Log.d(LOG_TAG, "compare fails:" + activateStr + "," + inputStr);
+                return false;
+            }
+        }
+        Log.d(LOG_TAG, "compare success");
+        return true;
+    }
+}
diff --git a/src/com/android/phone/GsmUmtsCallForwardOptions.java b/src/com/android/phone/GsmUmtsCallForwardOptions.java
index 6d80621..b8ea8fd 100644
--- a/src/com/android/phone/GsmUmtsCallForwardOptions.java
+++ b/src/com/android/phone/GsmUmtsCallForwardOptions.java
@@ -4,6 +4,7 @@
 import android.content.Intent;
 import android.database.Cursor;
 import android.os.Bundle;
+import android.os.PersistableBundle;
 import android.preference.Preference;
 import android.preference.PreferenceScreen;
 import android.telephony.CarrierConfigManager;
@@ -47,6 +48,7 @@
     private Phone mPhone;
     private SubscriptionInfoHelper mSubscriptionInfoHelper;
     private boolean mReplaceInvalidCFNumbers;
+    private boolean mCallForwardByUssd;
 
     @Override
     protected void onCreate(Bundle icicle) {
@@ -59,11 +61,18 @@
                 getActionBar(), getResources(), R.string.call_forwarding_settings_with_label);
         mPhone = mSubscriptionInfoHelper.getPhone();
 
-        CarrierConfigManager carrierConfig = (CarrierConfigManager)
-                getSystemService(CARRIER_CONFIG_SERVICE);
-        if (carrierConfig != null) {
-            mReplaceInvalidCFNumbers = carrierConfig.getConfig().getBoolean(
+        PersistableBundle b = null;
+        if (mSubscriptionInfoHelper.hasSubId()) {
+            b = PhoneGlobals.getInstance().getCarrierConfigForSubId(
+                    mSubscriptionInfoHelper.getSubId());
+        } else {
+            b = PhoneGlobals.getInstance().getCarrierConfig();
+        }
+        if (b != null) {
+            mReplaceInvalidCFNumbers = b.getBoolean(
                     CarrierConfigManager.KEY_CALL_FORWARDING_MAP_NON_NUMBER_TO_VOICEMAIL_BOOL);
+            mCallForwardByUssd = b.getBoolean(
+                    CarrierConfigManager.KEY_USE_CALL_FORWARDING_USSD_BOOL);
         }
 
         PreferenceScreen prefSet = getPreferenceScreen();
@@ -82,6 +91,18 @@
         mPreferences.add(mButtonCFNRy);
         mPreferences.add(mButtonCFNRc);
 
+        if (mCallForwardByUssd) {
+            //the call forwarding ussd command's behavior is similar to the call forwarding when
+            //unanswered,so only display the call forwarding when unanswered item.
+            prefSet.removePreference(mButtonCFU);
+            prefSet.removePreference(mButtonCFB);
+            prefSet.removePreference(mButtonCFNRc);
+            mPreferences.remove(mButtonCFU);
+            mPreferences.remove(mButtonCFB);
+            mPreferences.remove(mButtonCFNRc);
+            mButtonCFNRy.setDependency(null);
+        }
+
         // we wait to do the initialization until onResume so that the
         // TimeConsumingPreferenceActivity dialog can display as it
         // relies on onResume / onPause to maintain its foreground state.
@@ -104,7 +125,7 @@
             if (mIcicle == null) {
                 Log.d(LOG_TAG, "start to init ");
                 CallForwardEditPreference pref = mPreferences.get(mInitIndex);
-                pref.init(this, mPhone, mReplaceInvalidCFNumbers);
+                pref.init(this, mPhone, mReplaceInvalidCFNumbers, mCallForwardByUssd);
                 pref.startCallForwardOptionsQuery();
 
             } else {
@@ -117,7 +138,7 @@
                     CallForwardInfo cf = new CallForwardInfo();
                     cf.number = bundle.getString(KEY_NUMBER);
                     cf.status = bundle.getInt(KEY_STATUS);
-                    pref.init(this, mPhone, mReplaceInvalidCFNumbers);
+                    pref.init(this, mPhone, mReplaceInvalidCFNumbers, mCallForwardByUssd);
                     pref.restoreCallForwardInfo(cf);
                 }
             }
@@ -147,7 +168,7 @@
         if (mInitIndex < mPreferences.size()-1 && !isFinishing()) {
             mInitIndex++;
             CallForwardEditPreference pref = mPreferences.get(mInitIndex);
-            pref.init(this, mPhone, mReplaceInvalidCFNumbers);
+            pref.init(this, mPhone, mReplaceInvalidCFNumbers, mCallForwardByUssd);
             pref.startCallForwardOptionsQuery();
         }
 
