Merge cherrypicks of ['googleplex-android-review.googlesource.com/20928946'] into tm-qpr2-b-release.

Change-Id: I799d11e2e29f9d90771d421e7bd8a02a90c27af1
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
index 27a8697..738439a 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
@@ -891,9 +891,15 @@
                 Rlog.d(LOG_TAG, "processCode: isShortCode");
 
                 // These just get treated as USSD.
-                Rlog.d(LOG_TAG, "processCode: Sending short code '"
-                       + mDialingNumber + "' over CS pipe.");
-                throw new CallStateException(Phone.CS_FALLBACK);
+                if (isUssdOverImsAllowed()) {
+                    Rlog.d(LOG_TAG, "processCode: Sending short code '"
+                           + mDialingNumber + "' over IMS pipe.");
+                    sendUssd(mDialingNumber);
+                } else {
+                    Rlog.d(LOG_TAG, "processCode: Sending short code '"
+                           + mDialingNumber + "' over CS pipe.");
+                    throw new CallStateException(Phone.CS_FALLBACK);
+                }
             } else if (isServiceCodeCallForwarding(mSc)) {
                 Rlog.d(LOG_TAG, "processCode: is CF");
 
@@ -1104,47 +1110,11 @@
                     throw new RuntimeException ("Invalid or Unsupported MMI Code");
                 }
             } else if (mPoundString != null) {
-                if (mContext.getResources().getBoolean(
-                        com.android.internal.R.bool.config_allow_ussd_over_ims)) {
-                    int ussd_method = getIntCarrierConfig(
-                                    CarrierConfigManager.KEY_CARRIER_USSD_METHOD_INT);
-
-                    switch (ussd_method) {
-                        case USSD_OVER_CS_PREFERRED:
-                            // We'll normally send USSD over the CS pipe, but if it happens that
-                            // the CS phone is out of service, we'll just try over IMS instead.
-                            if (mPhone.getDefaultPhone().getServiceStateTracker().mSS.getState()
-                                    == STATE_IN_SERVICE) {
-                                Rlog.i(LOG_TAG, "processCode: Sending ussd string '"
-                                        + Rlog.pii(LOG_TAG, mPoundString) + "' over CS pipe "
-                                        + "(allowed over ims).");
-                                throw new CallStateException(Phone.CS_FALLBACK);
-                            } else {
-                                Rlog.i(LOG_TAG, "processCode: CS is out of service, "
-                                        + "sending ussd string '"
-                                        + Rlog.pii(LOG_TAG, mPoundString) + "' over IMS pipe.");
-                                sendUssd(mPoundString);
-                            }
-                            break;
-                        case USSD_OVER_IMS_PREFERRED:
-                        case USSD_OVER_IMS_ONLY:
-                            Rlog.i(LOG_TAG, "processCode: Sending ussd string '"
-                                    + Rlog.pii(LOG_TAG, mPoundString) + "' over IMS pipe.");
-                            sendUssd(mPoundString);
-                            break;
-                        case USSD_OVER_CS_ONLY:
-                            Rlog.i(LOG_TAG, "processCode: Sending ussd string '"
-                                    + Rlog.pii(LOG_TAG, mPoundString) + "' over CS pipe.");
-                            throw new CallStateException(Phone.CS_FALLBACK);
-                        default:
-                            Rlog.i(LOG_TAG, "processCode: Sending ussd string '"
-                                    + Rlog.pii(LOG_TAG, mPoundString) + "' over CS pipe."
-                                    + "(unsupported method)");
-                            throw new CallStateException(Phone.CS_FALLBACK);
-                    }
+                if (isUssdOverImsAllowed()) {
+                    Rlog.i(LOG_TAG, "processCode: Sending ussd string '"
+                            + Rlog.pii(LOG_TAG, mPoundString) + "' over IMS pipe.");
+                    sendUssd(mPoundString);
                 } else {
-                    // USSD codes are not supported over IMS due to modem limitations; send over
-                    // the CS pipe instead.  This should be fixed in the future.
                     Rlog.i(LOG_TAG, "processCode: Sending ussd string '"
                             + Rlog.pii(LOG_TAG, mPoundString) + "' over CS pipe.");
                     throw new CallStateException(Phone.CS_FALLBACK);
@@ -1161,6 +1131,40 @@
         }
     }
 
+    private boolean isUssdOverImsAllowed() {
+        if (mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_allow_ussd_over_ims)) {
+            int ussd_method = getIntCarrierConfig(
+                            CarrierConfigManager.KEY_CARRIER_USSD_METHOD_INT);
+
+            switch (ussd_method) {
+                case USSD_OVER_CS_PREFERRED:
+                    // We'll normally send USSD over the CS pipe, but if it happens that
+                    // the CS phone is out of service, we'll just try over IMS instead.
+                    if (mPhone.getDefaultPhone().getServiceStateTracker().mSS.getState()
+                            == STATE_IN_SERVICE) {
+                        return false;
+                    } else {
+                        Rlog.i(LOG_TAG, "isUssdOverImsAllowed: CS is out of service");
+                        return true;
+                    }
+                case USSD_OVER_IMS_PREFERRED:
+                case USSD_OVER_IMS_ONLY:
+                    return true;
+                case USSD_OVER_CS_ONLY:
+                    return false;
+                default:
+                    Rlog.i(LOG_TAG, "isUssdOverImsAllowed: Unsupported method");
+                    return false;
+            }
+        } else {
+            // USSD codes are not supported over IMS due to modem limitations; send over
+            // the CS pipe instead.  This should be fixed in the future.
+            Rlog.i(LOG_TAG, "isUssdOverImsAllowed: USSD over IMS pipe is not supported.");
+            return false;
+        }
+    }
+
     /**
      * Called from ImsPhone
      *
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
index 17a63dd..7750635 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
@@ -881,6 +881,9 @@
 
         mImsPhoneUT.dial("*135#", new ImsPhone.ImsDialArgs.Builder().build());
         verify(mImsCT).sendUSSD(eq("*135#"), any());
+
+        mImsPhoneUT.dial("91", new ImsPhone.ImsDialArgs.Builder().build());
+        verify(mImsCT).sendUSSD(eq("91"), any());
     }
 
     @Test
@@ -901,6 +904,13 @@
             errorCode = e.getMessage();
         }
         assertEquals(Phone.CS_FALLBACK, errorCode);
+
+        try {
+            mImsPhoneUT.dial("91", new ImsPhone.ImsDialArgs.Builder().build());
+        } catch (CallStateException e) {
+            errorCode = e.getMessage();
+        }
+        assertEquals(Phone.CS_FALLBACK, errorCode);
     }
 
     @Test
@@ -918,11 +928,18 @@
             errorCode = e.getMessage();
         }
         assertEquals(Phone.CS_FALLBACK, errorCode);
+
+        try {
+            mImsPhoneUT.dial("91", new ImsPhone.ImsDialArgs.Builder().build());
+        } catch (CallStateException e) {
+            errorCode = e.getMessage();
+        }
+        assertEquals(Phone.CS_FALLBACK, errorCode);
     }
 
     @Test
     @SmallTest
-    public void testSendUssdAllowUssdOverImswithIMSPreferred() throws Exception {
+    public void testSendUssdAllowUssdOverImsWithImsPreferred() throws Exception {
         Resources resources = mContext.getResources();
 
         mBundle.putInt(CarrierConfigManager.KEY_CARRIER_USSD_METHOD_INT,
@@ -933,11 +950,14 @@
 
         mImsPhoneUT.dial("*135#", new ImsPhone.ImsDialArgs.Builder().build());
         verify(mImsCT).sendUSSD(eq("*135#"), any());
+
+        mImsPhoneUT.dial("91", new ImsPhone.ImsDialArgs.Builder().build());
+        verify(mImsCT).sendUSSD(eq("91"), any());
     }
 
     @Test
     @SmallTest
-    public void testSendUssdAllowUssdOverImswithCSOnly() throws Exception {
+    public void testSendUssdAllowUssdOverImsWithCsOnly() throws Exception {
         String errorCode = "";
         Resources resources = mContext.getResources();
 
@@ -953,11 +973,18 @@
             errorCode = e.getMessage();
         }
         assertEquals(Phone.CS_FALLBACK, errorCode);
+
+        try {
+            mImsPhoneUT.dial("91", new ImsPhone.ImsDialArgs.Builder().build());
+        } catch (CallStateException e) {
+            errorCode = e.getMessage();
+        }
+        assertEquals(Phone.CS_FALLBACK, errorCode);
     }
 
     @Test
     @SmallTest
-    public void testSendUssdAllowUssdOverImswithIMSOnly() throws Exception {
+    public void testSendUssdAllowUssdOverImsWithImsOnly() throws Exception {
         Resources resources = mContext.getResources();
 
         mBundle.putInt(CarrierConfigManager.KEY_CARRIER_USSD_METHOD_INT,
@@ -968,6 +995,9 @@
 
         mImsPhoneUT.dial("*135#", new ImsPhone.ImsDialArgs.Builder().build());
         verify(mImsCT).sendUSSD(eq("*135#"), any());
+
+        mImsPhoneUT.dial("91", new ImsPhone.ImsDialArgs.Builder().build());
+        verify(mImsCT).sendUSSD(eq("91"), any());
     }
 
     @Test