/**
   * Some dial strings in GSM are defined to do non-call setup things, such as modify or query
   * supplementary service settings (eg, call forwarding). These are generally referred to as "MMI
   * codes". We look to see if the dial string contains a valid MMI code (potentially with a dial
   * string at the end as well) and return info here.
   *
   * <p>If the dial string contains no MMI code, we return an instance with only "dialingNumber" set
   *
   * <p>Please see flow chart in TS 22.030 6.5.3.2
   */
  static GsmMmiCode newFromDialString(String dialString, GSMPhone phone, UiccCardApplication app) {
    Matcher m;
    GsmMmiCode ret = null;

    if (SystemProperties.getBoolean("ro.config.multimode_cdma", false)) {
      m = sPatternSuppServiceGlobalDev.matcher(dialString);
      if (m.matches()) {
        ret = new GsmMmiCode(phone, app);
        ret.action = makeEmptyNull(m.group(MATCH_GROUP_ACTION));
        String DialCode = makeEmptyNull(m.group(MATCH_GROUP_SERVICE_CODE));
        if (DialCode.equals(SC_GLOBALDEV_VM)) {
          ret.sc = SC_GLOBALDEV_VM;
          ret.dialingNumber = "+1" + phone.getMdn();
          return ret;
        } else if (DialCode.equals(SC_GLOBALDEV_CS)) {
          ret.sc = SC_GLOBALDEV_CS;
          ret.dialingNumber = GLOBALDEV_CS;
          return ret;
        } else if (DialCode.length() >= 3 && DialCode.startsWith(SC_GLOBALDEV_CLIR_INVK)) {
          // Dial "#31#PhoneNum" to invoke CLIR temporarily
          dialString = ACTION_DEACTIVATE + SC_CLIR + ACTION_DEACTIVATE + DialCode.substring(2);
        } else if (DialCode.length() >= 3 && DialCode.startsWith(SC_GLOBALDEV_CLIR_SUPP)) {
          // Dial "*31#PhoneNum" to suppress CLIR temporarily
          dialString = ACTION_ACTIVATE + SC_CLIR + ACTION_DEACTIVATE + DialCode.substring(2);
        }
      }
    }

    m = sPatternSuppService.matcher(dialString);

    // Is this formatted like a standard supplementary service code?
    if (m.matches()) {
      ret = new GsmMmiCode(phone, app);
      ret.poundString = makeEmptyNull(m.group(MATCH_GROUP_POUND_STRING));
      ret.action = makeEmptyNull(m.group(MATCH_GROUP_ACTION));
      ret.sc = makeEmptyNull(m.group(MATCH_GROUP_SERVICE_CODE));
      ret.sia = makeEmptyNull(m.group(MATCH_GROUP_SIA));
      ret.sib = makeEmptyNull(m.group(MATCH_GROUP_SIB));
      ret.sic = makeEmptyNull(m.group(MATCH_GROUP_SIC));
      ret.pwd = makeEmptyNull(m.group(MATCH_GROUP_PWD_CONFIRM));
      ret.dialingNumber = makeEmptyNull(m.group(MATCH_GROUP_DIALING_NUMBER));

    } else if (dialString.endsWith("#")) {
      // TS 22.030 sec 6.5.3.2
      // "Entry of any characters defined in the 3GPP TS 23.038 [8] Default Alphabet
      // (up to the maximum defined in 3GPP TS 24.080 [10]), followed by #SEND".

      ret = new GsmMmiCode(phone, app);
      ret.poundString = dialString;
    } else if (isTwoDigitShortCode(phone.getContext(), dialString)) {
      // Is a country-specific exception to short codes as defined in TS 22.030, 6.5.3.2
      ret = null;
    } else if (isShortCode(dialString, phone)) {
      // this may be a short code, as defined in TS 22.030, 6.5.3.2
      ret = new GsmMmiCode(phone, app);
      ret.dialingNumber = dialString;
    }

    return ret;
  }
 /**
  * Helper function for newFromDialString. Returns true if dialString appears to be a short code
  * AND conditions are correct for it to be treated as such.
  */
 private static boolean isShortCode(String dialString, GSMPhone phone) {
   // check for any  Adapt change requirements.
   boolean shortCodeExclusionFlag = false;
   if (SystemProperties.getBoolean("persist.cust.tel.adapt", false)) {
     if (dialString.length() == 2) {
       Log.i(LOG_TAG, "Adapt, Number needs to be checked for short code exclusion list");
       shortCodeExclusionFlag = isExcludedShortCode(dialString);
     }
   }
   // Refer to TS 22.030 Figure 3.5.3.2:
   // A 1 or 2 digit "short code" is treated as USSD if it is entered while on a call or
   // does not satisfy the condition (exactly 2 digits && starts with '1').
   return ((dialString != null && dialString.length() <= 2)
       && !PhoneNumberUtils.isEmergencyNumber(dialString)
       && (phone.isInCall()
           || !((dialString.length() == 2 && dialString.charAt(0) == '1')
               || shortCodeExclusionFlag
               /*
                * While contrary to TS 22.030, there is strong precedence for
                * treating "0" and "00" as call setup strings.
                */
               || dialString.equals("0")
               || dialString.equals("00"))));
 }