Merge change 21006
* changes: Fix the issue of incorrect conversion of the plus sign in a dial string.
This commit is contained in:
@@ -26,8 +26,11 @@ import android.provider.ContactsContract;
|
||||
import android.text.Editable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.SparseIntArray;
|
||||
|
||||
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_IDP_STRING;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -57,6 +60,9 @@ public class PhoneNumberUtils
|
||||
public static final int TOA_International = 0x91;
|
||||
public static final int TOA_Unknown = 0x81;
|
||||
|
||||
static final String LOG_TAG = "PhoneNumberUtils";
|
||||
private static final boolean DBG = false;
|
||||
|
||||
/*
|
||||
* global-phone-number = ["+"] 1*( DIGIT / written-sep )
|
||||
* written-sep = ("-"/".")
|
||||
@@ -227,6 +233,9 @@ public class PhoneNumberUtils
|
||||
}
|
||||
}
|
||||
|
||||
private static void log(String msg) {
|
||||
Log.d(LOG_TAG, msg);
|
||||
}
|
||||
/** index of the last character of the network portion
|
||||
* (eg anything after is a post-dial string)
|
||||
*/
|
||||
@@ -741,6 +750,14 @@ public class PhoneNumberUtils
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isNonSeparator(String address) {
|
||||
for (int i = 0, count = address.length(); i < count; i++) {
|
||||
if (!isNonSeparator(address.charAt(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Note: calls extractNetworkPortion(), so do not use for
|
||||
* SIM EF[ADN] style records
|
||||
@@ -1229,4 +1246,261 @@ public class PhoneNumberUtils
|
||||
KEYPAD_MAP.put('w', '9'); KEYPAD_MAP.put('x', '9'); KEYPAD_MAP.put('y', '9'); KEYPAD_MAP.put('z', '9');
|
||||
KEYPAD_MAP.put('W', '9'); KEYPAD_MAP.put('X', '9'); KEYPAD_MAP.put('Y', '9'); KEYPAD_MAP.put('Z', '9');
|
||||
}
|
||||
|
||||
//================ Plus Code formatting =========================
|
||||
private static final char PLUS_SIGN_CHAR = '+';
|
||||
private static final String PLUS_SIGN_STRING = "+";
|
||||
private static final String NANP_IDP_STRING = "011";
|
||||
private static final int NANP_LENGTH = 10;
|
||||
|
||||
/**
|
||||
* This function checks if there is a plus sign (+) in the passed-in dialing number.
|
||||
* If there is, it processes the plus sign based on the default telephone
|
||||
* numbering plan of the system when the phone is activated and the current
|
||||
* telephone numbering plan of the system that the phone is camped on.
|
||||
* Currently, we only support the case that the default and current telephone
|
||||
* numbering plans are North American Numbering Plan(NANP).
|
||||
*
|
||||
* The passed-in dialStr should only contain the valid format as described below,
|
||||
* 1) the 1st character in the dialStr should be one of the really dialable
|
||||
* characters listed below
|
||||
* ISO-LATIN characters 0-9, *, # , +
|
||||
* 2) the dialStr should already strip out the separator characters,
|
||||
* every character in the dialStr should be one of the non separator characters
|
||||
* listed below
|
||||
* ISO-LATIN characters 0-9, *, # , +, WILD, WAIT, PAUSE
|
||||
*
|
||||
* Otherwise, this function returns the dial string passed in
|
||||
*
|
||||
* This API is for CDMA only
|
||||
*
|
||||
* @hide TODO: pending API Council approval
|
||||
*/
|
||||
public static String cdmaCheckAndProcessPlusCode(String dialStr) {
|
||||
if (!TextUtils.isEmpty(dialStr)) {
|
||||
if (isReallyDialable(dialStr.charAt(0)) &&
|
||||
isNonSeparator(dialStr)) {
|
||||
return cdmaCheckAndProcessPlusCodeByNumberFormat(dialStr,
|
||||
getFormatTypeForLocale(Locale.getDefault()));
|
||||
}
|
||||
}
|
||||
return dialStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function should be called from checkAndProcessPlusCode only
|
||||
* And it is used for test purpose also.
|
||||
*
|
||||
* It checks the dial string by looping through the network portion,
|
||||
* post dial portion 1, post dial porting 2, etc. If there is any
|
||||
* plus sign, then process the plus sign.
|
||||
* Currently, this function supports the plus sign conversion within NANP only.
|
||||
* Specifically, it handles the plus sign in the following ways:
|
||||
* 1)+NANP or +1NANP,remove +, e.g.
|
||||
* +8475797000 is converted to 8475797000,
|
||||
* +18475797000 is converted to 18475797000,
|
||||
* 2)+non-NANP Numbers,replace + with the current NANP IDP, e.g,
|
||||
* +11875767800 is converted to 01111875767800
|
||||
* 3)+NANP in post dial string(s), e.g.
|
||||
* 8475797000;+8475231753 is converted to 8475797000;8475231753
|
||||
*
|
||||
* This function returns the original dial string if locale/numbering plan
|
||||
* aren't supported.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static String cdmaCheckAndProcessPlusCodeByNumberFormat(String dialStr,int numFormat) {
|
||||
String retStr = dialStr;
|
||||
|
||||
// Checks if the plus sign character is in the passed-in dial string
|
||||
if (dialStr != null &&
|
||||
dialStr.lastIndexOf(PLUS_SIGN_STRING) != -1) {
|
||||
|
||||
String postDialStr = null;
|
||||
String tempDialStr = dialStr;
|
||||
|
||||
// Sets the retStr to null since the conversion will be performed below.
|
||||
retStr = null;
|
||||
if (DBG) log("checkAndProcessPlusCode,dialStr=" + dialStr);
|
||||
// This routine is to process the plus sign in the dial string by loop through
|
||||
// the network portion, post dial portion 1, post dial portion 2... etc. if
|
||||
// applied
|
||||
do {
|
||||
String networkDialStr;
|
||||
|
||||
// Format the string based on the rules for the country the number is from
|
||||
if (numFormat != FORMAT_NANP) {
|
||||
// TODO: to support NANP international conversion and
|
||||
// other telephone numbering plan
|
||||
// Currently the phone is ever used in non-NANP system
|
||||
// return the original dial string
|
||||
Log.e("checkAndProcessPlusCode:non-NANP not supported", dialStr);
|
||||
return dialStr;
|
||||
} else {
|
||||
// For the case that the default and current telephone
|
||||
// numbering plans are NANP
|
||||
networkDialStr = extractNetworkPortion(tempDialStr);
|
||||
// Handles the conversion within NANP
|
||||
networkDialStr = processPlusCodeWithinNanp(networkDialStr);
|
||||
}
|
||||
// Concatenates the string that is converted from network portion
|
||||
if (!TextUtils.isEmpty(networkDialStr)) {
|
||||
if (retStr == null) {
|
||||
retStr = networkDialStr;
|
||||
} else {
|
||||
retStr = retStr.concat(networkDialStr);
|
||||
}
|
||||
} else {
|
||||
// This should never happen since we checked the if dialStr is null
|
||||
// and if it contains the plus sign in the begining of this function.
|
||||
// The plus sign is part of the network portion.
|
||||
Log.e("checkAndProcessPlusCode: null newDialStr", networkDialStr);
|
||||
return dialStr;
|
||||
}
|
||||
postDialStr = extractPostDialPortion(tempDialStr);
|
||||
if (!TextUtils.isEmpty(postDialStr)) {
|
||||
int dialableIndex = findDialableIndexFromPostDialStr(postDialStr);
|
||||
|
||||
// dialableIndex should always be greater than 0
|
||||
if (dialableIndex >= 1) {
|
||||
retStr = appendPwCharBackToOrigDialStr(dialableIndex,
|
||||
retStr,postDialStr);
|
||||
// Skips the P/W character, extracts the dialable portion
|
||||
tempDialStr = postDialStr.substring(dialableIndex);
|
||||
} else {
|
||||
// Non-dialable character such as P/W should not be at the end of
|
||||
// the dial string after P/W processing in CdmaConnection.java
|
||||
// Set the postDialStr to "" to break out of the loop
|
||||
if (dialableIndex < 0) {
|
||||
postDialStr = "";
|
||||
}
|
||||
Log.e("wrong postDialStr=", postDialStr);
|
||||
}
|
||||
}
|
||||
if (DBG) log("checkAndProcessPlusCode,postDialStr=" + postDialStr);
|
||||
} while (!TextUtils.isEmpty(postDialStr) && !TextUtils.isEmpty(tempDialStr));
|
||||
}
|
||||
return retStr;
|
||||
}
|
||||
|
||||
// This function gets the default international dialing prefix
|
||||
private static String getDefaultIdp( ) {
|
||||
String ps = null;
|
||||
SystemProperties.get(PROPERTY_IDP_STRING, ps);
|
||||
if (TextUtils.isEmpty(ps)) {
|
||||
ps = NANP_IDP_STRING;
|
||||
}
|
||||
return ps;
|
||||
}
|
||||
|
||||
private static boolean isTwoToNine (char c) {
|
||||
if (c >= '2' && c <= '9') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function checks if the passed in string conforms to the NANP format
|
||||
* i.e. NXX-NXX-XXXX, N is any digit 2-9 and X is any digit 0-9
|
||||
*/
|
||||
private static boolean isNanp (String dialStr) {
|
||||
boolean retVal = false;
|
||||
if (dialStr != null) {
|
||||
if (dialStr.length() == NANP_LENGTH) {
|
||||
if (isTwoToNine(dialStr.charAt(0)) &&
|
||||
isTwoToNine(dialStr.charAt(3))) {
|
||||
retVal = true;
|
||||
for (int i=1; i<NANP_LENGTH; i++ ) {
|
||||
char c=dialStr.charAt(i);
|
||||
if (!PhoneNumberUtils.isISODigit(c)) {
|
||||
retVal = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log.e("isNanp: null dialStr passed in", dialStr);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function checks if the passed in string conforms to 1-NANP format
|
||||
*/
|
||||
private static boolean isOneNanp(String dialStr) {
|
||||
boolean retVal = false;
|
||||
if (dialStr != null) {
|
||||
String newDialStr = dialStr.substring(1);
|
||||
if ((dialStr.charAt(0) == '1') && isNanp(newDialStr)) {
|
||||
retVal = true;
|
||||
}
|
||||
} else {
|
||||
Log.e("isOneNanp: null dialStr passed in", dialStr);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function handles the plus code conversion within NANP CDMA network
|
||||
* If the number format is
|
||||
* 1)+NANP or +1NANP,remove +,
|
||||
* 2)+non-NANP Numbers,replace + with the current IDP
|
||||
*/
|
||||
private static String processPlusCodeWithinNanp(String networkDialStr) {
|
||||
String retStr = networkDialStr;
|
||||
|
||||
if (DBG) log("processPlusCodeWithinNanp,networkDialStr=" + networkDialStr);
|
||||
// If there is a plus sign at the beginning of the dial string,
|
||||
// Convert the plus sign to the default IDP since it's an international number
|
||||
if (networkDialStr != null &
|
||||
networkDialStr.charAt(0) == PLUS_SIGN_CHAR &&
|
||||
networkDialStr.length() > 1) {
|
||||
String newStr = networkDialStr.substring(1);
|
||||
if (isNanp(newStr) || isOneNanp(newStr)) {
|
||||
// Remove the leading plus sign
|
||||
retStr = newStr;
|
||||
} else {
|
||||
String idpStr = getDefaultIdp();
|
||||
// Replaces the plus sign with the default IDP
|
||||
retStr = networkDialStr.replaceFirst("[+]", idpStr);
|
||||
}
|
||||
}
|
||||
if (DBG) log("processPlusCodeWithinNanp,retStr=" + retStr);
|
||||
return retStr;
|
||||
}
|
||||
|
||||
// This function finds the index of the dialable character(s)
|
||||
// in the post dial string
|
||||
private static int findDialableIndexFromPostDialStr(String postDialStr) {
|
||||
for (int index = 0;index < postDialStr.length();index++) {
|
||||
char c = postDialStr.charAt(index);
|
||||
if (isReallyDialable(c)) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// This function appends the non-diablable P/W character to the original
|
||||
// dial string based on the dialable index passed in
|
||||
private static String
|
||||
appendPwCharBackToOrigDialStr(int dialableIndex,String origStr, String dialStr) {
|
||||
String retStr;
|
||||
|
||||
// There is only 1 P/W character before the dialable characters
|
||||
if (dialableIndex == 1) {
|
||||
StringBuilder ret = new StringBuilder(origStr);
|
||||
ret = ret.append(dialStr.charAt(0));
|
||||
retStr = ret.toString();
|
||||
} else {
|
||||
// It means more than 1 P/W characters in the post dial string,
|
||||
// appends to retStr
|
||||
String nonDigitStr = dialStr.substring(0,dialableIndex);
|
||||
retStr = origStr.concat(nonDigitStr);
|
||||
}
|
||||
return retStr;
|
||||
}
|
||||
}
|
||||
|
||||
37
telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
Normal file → Executable file
37
telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
Normal file → Executable file
@@ -818,15 +818,12 @@ public class CdmaConnection extends Connection {
|
||||
return c == PhoneNumberUtils.WAIT;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// This function is to find the next PAUSE character index if
|
||||
// multiple pauses in a row. Otherwise it finds the next non PAUSE or
|
||||
// non WAIT character index.
|
||||
private static int
|
||||
findNextPCharOrNonPOrNonWCharIndex(String phoneNumber, int currIndex) {
|
||||
boolean wMatched = false;
|
||||
boolean wMatched = isWait(phoneNumber.charAt(currIndex));
|
||||
int index = currIndex + 1;
|
||||
int length = phoneNumber.length();
|
||||
while (index < length) {
|
||||
@@ -863,17 +860,17 @@ public class CdmaConnection extends Connection {
|
||||
// Append the PW char
|
||||
ret = (isPause(c)) ? PhoneNumberUtils.PAUSE : PhoneNumberUtils.WAIT;
|
||||
|
||||
// if there is a PAUSE in at the begining of PW character sequences, and this
|
||||
// PW character sequences has more than 2 PAUSE and WAIT Characters,skip P, append W
|
||||
if (isPause(c) && (nextNonPwCharIndex > (currPwIndex + 1))) {
|
||||
// if there is a PAUSE in at the beginning of PW character sequences, and this
|
||||
// PW character sequences has more than 2 PAUSE and WAIT Characters,skip PAUSE,
|
||||
// append WAIT.
|
||||
if (isPause(c) && (nextNonPwCharIndex > (currPwIndex + 2))) {
|
||||
ret = PhoneNumberUtils.WAIT;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* format orignal dial string
|
||||
* format original dial string
|
||||
* 1) convert international dialing prefix "+" to
|
||||
* string specified per region
|
||||
*
|
||||
@@ -892,20 +889,10 @@ public class CdmaConnection extends Connection {
|
||||
StringBuilder ret = new StringBuilder();
|
||||
char c;
|
||||
int currIndex = 0;
|
||||
|
||||
while (currIndex < length) {
|
||||
c = phoneNumber.charAt(currIndex);
|
||||
if (PhoneNumberUtils.isDialable(c)) {
|
||||
if (c == '+') {
|
||||
String ps = null;
|
||||
SystemProperties.get(TelephonyProperties.PROPERTY_IDP_STRING, ps);
|
||||
if (TextUtils.isEmpty(ps)) {
|
||||
ps = "011";
|
||||
}
|
||||
ret.append(ps);
|
||||
} else {
|
||||
ret.append(c);
|
||||
}
|
||||
} else if (isPause(c) || isWait(c)) {
|
||||
if (isPause(c) || isWait(c)) {
|
||||
if (currIndex < length - 1) {
|
||||
// if PW not at the end
|
||||
int nextIndex = findNextPCharOrNonPOrNonWCharIndex(phoneNumber, currIndex);
|
||||
@@ -913,8 +900,10 @@ public class CdmaConnection extends Connection {
|
||||
if (nextIndex < length) {
|
||||
char pC = findPOrWCharToAppend(phoneNumber, currIndex, nextIndex);
|
||||
ret.append(pC);
|
||||
// If PW char is immediately followed by non-PW char
|
||||
if (nextIndex > (currIndex + 1)) {
|
||||
// If PW char sequence has more than 2 PW characters,
|
||||
// skip to the last character since the sequence already be
|
||||
// converted to WAIT character
|
||||
if (nextIndex > (currIndex + 2)) {
|
||||
currIndex = nextIndex - 1;
|
||||
}
|
||||
} else if (nextIndex == length) {
|
||||
@@ -927,7 +916,7 @@ public class CdmaConnection extends Connection {
|
||||
}
|
||||
currIndex++;
|
||||
}
|
||||
return ret.toString();
|
||||
return PhoneNumberUtils.cdmaCheckAndProcessPlusCode(ret.toString());
|
||||
}
|
||||
|
||||
private void log(String msg) {
|
||||
|
||||
@@ -335,4 +335,73 @@ public class PhoneNumberUtilsTest extends TestCase {
|
||||
assertEquals("(800) 222-3334",
|
||||
PhoneNumberUtils.convertKeypadLettersToDigits("(800) ABC-DEFG"));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testCheckAndProcessPlusCode() {
|
||||
assertEquals("8475797000",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+8475797000"));
|
||||
assertEquals("18475797000",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+18475797000"));
|
||||
assertEquals("0111234567",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+1234567"));
|
||||
assertEquals("01123456700000",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+23456700000"));
|
||||
assertEquals("01111875767800",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+11875767800"));
|
||||
assertEquals("8475797000,18475231753",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,+18475231753"));
|
||||
assertEquals("8475797000,18475231753",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+8475797000,+18475231753"));
|
||||
assertEquals("8475797000;8475231753",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000;+8475231753"));
|
||||
assertEquals("8475797000,0111234567",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,+1234567"));
|
||||
assertEquals("847597000;01111875767000",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCode("847597000;+11875767000"));
|
||||
assertEquals("8475797000,,8475231753",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,,+8475231753"));
|
||||
assertEquals("8475797000;,8475231753",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000;,+8475231753"));
|
||||
assertEquals("8475797000,;18475231753",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,;+18475231753"));
|
||||
assertEquals("8475797000;,01111875767000",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000;,+11875767000"));
|
||||
assertEquals("8475797000,;01111875767000",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,;+11875767000"));
|
||||
assertEquals("8475797000,,,01111875767000",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,,,+11875767000"));
|
||||
assertEquals("8475797000;,,01111875767000",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000;,,+11875767000"));
|
||||
assertEquals("+;,8475797000",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+;,8475797000"));
|
||||
assertEquals("8475797000,",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,"));
|
||||
assertEquals("847+579-7000",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCode("847+579-7000"));
|
||||
assertEquals(",8475797000",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCode(",8475797000"));
|
||||
assertEquals(";;8475797000,,",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCode(";;8475797000,,"));
|
||||
assertEquals("+this+is$weird;,+",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+this+is$weird;,+"));
|
||||
assertEquals("",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCode(""));
|
||||
assertNull(PhoneNumberUtils.cdmaCheckAndProcessPlusCode(null));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testCheckAndProcessPlusCodeByNumberFormat() {
|
||||
assertEquals("+8475797000",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCodeByNumberFormat("+8475797000",
|
||||
PhoneNumberUtils.FORMAT_JAPAN));
|
||||
assertEquals("+0384756700",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCodeByNumberFormat("+0384756700",
|
||||
PhoneNumberUtils.FORMAT_JAPAN));
|
||||
assertEquals("+1234567",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCodeByNumberFormat("+1234567",
|
||||
PhoneNumberUtils.FORMAT_UNKNOWN));
|
||||
assertEquals("+23456700000",
|
||||
PhoneNumberUtils.cdmaCheckAndProcessPlusCodeByNumberFormat("+23456700000",
|
||||
PhoneNumberUtils.FORMAT_UNKNOWN));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user