Skip to content

Commit 59882fb

Browse files
David BrownAndroid (Google) Code Review
authored andcommitted
Merge "Add "potential" variants for PhoneNumberUtils.isEmergencyNumber()" into ics-mr0
2 parents 1999812 + 1a81169 commit 59882fb

File tree

2 files changed

+244
-49
lines changed

2 files changed

+244
-49
lines changed

telephony/java/android/telephony/PhoneNumberUtils.java

Lines changed: 198 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,14 +1513,65 @@ public static String normalizeNumber(String phoneNumber) {
15131513
static final int MIN_MATCH = 7;
15141514

15151515
/**
1516-
* isEmergencyNumber: checks a given number against the list of
1517-
* emergency numbers provided by the RIL and SIM card.
1516+
* Checks a given number against the list of
1517+
* emergency numbers provided by the RIL and SIM card.
15181518
*
15191519
* @param number the number to look up.
1520-
* @return if the number is in the list of emergency numbers
1521-
* listed in the ril / sim, then return true, otherwise false.
1520+
* @return true if the number is in the list of emergency numbers
1521+
* listed in the RIL / SIM, otherwise return false.
15221522
*/
15231523
public static boolean isEmergencyNumber(String number) {
1524+
// Return true only if the specified number *exactly* matches
1525+
// one of the emergency numbers listed by the RIL / SIM.
1526+
return isEmergencyNumberInternal(number, true /* useExactMatch */);
1527+
}
1528+
1529+
/**
1530+
* Checks if given number might *potentially* result in
1531+
* a call to an emergency service on the current network.
1532+
*
1533+
* Specifically, this method will return true if the specified number
1534+
* is an emergency number according to the list managed by the RIL or
1535+
* SIM, *or* if the specified number simply starts with the same
1536+
* digits as any of the emergency numbers listed in the RIL / SIM.
1537+
*
1538+
* This method is intended for internal use by the phone app when
1539+
* deciding whether to allow ACTION_CALL intents from 3rd party apps
1540+
* (where we're required to *not* allow emergency calls to be placed.)
1541+
*
1542+
* @param number the number to look up.
1543+
* @return true if the number is in the list of emergency numbers
1544+
* listed in the RIL / SIM, *or* if the number starts with the
1545+
* same digits as any of those emergency numbers.
1546+
*
1547+
* @hide
1548+
*/
1549+
public static boolean isPotentialEmergencyNumber(String number) {
1550+
// Check against the emergency numbers listed by the RIL / SIM,
1551+
// and *don't* require an exact match.
1552+
return isEmergencyNumberInternal(number, false /* useExactMatch */);
1553+
}
1554+
1555+
/**
1556+
* Helper function for isEmergencyNumber(String) and
1557+
* isPotentialEmergencyNumber(String).
1558+
*
1559+
* @param number the number to look up.
1560+
*
1561+
* @param useExactMatch if true, consider a number to be an emergency
1562+
* number only if it *exactly* matches a number listed in
1563+
* the RIL / SIM. If false, a number is considered to be an
1564+
* emergency number if it simply starts with the same digits
1565+
* as any of the emergency numbers listed in the RIL / SIM.
1566+
* (Setting useExactMatch to false allows you to identify
1567+
* number that could *potentially* result in emergency calls
1568+
* since many networks will actually ignore trailing digits
1569+
* after a valid emergency number.)
1570+
*
1571+
* @return true if the number is in the list of emergency numbers
1572+
* listed in the RIL / sim, otherwise return false.
1573+
*/
1574+
private static boolean isEmergencyNumberInternal(String number, boolean useExactMatch) {
15241575
// If the number passed in is null, just return false:
15251576
if (number == null) return false;
15261577

@@ -1540,16 +1591,26 @@ public static boolean isEmergencyNumber(String number) {
15401591
// searches through the comma-separated list for a match,
15411592
// return true if one is found.
15421593
for (String emergencyNum : numbers.split(",")) {
1543-
if (number.startsWith(emergencyNum)) {
1544-
return true;
1594+
if (useExactMatch) {
1595+
if (number.equals(emergencyNum)) {
1596+
return true;
1597+
}
1598+
} else {
1599+
if (number.startsWith(emergencyNum)) {
1600+
return true;
1601+
}
15451602
}
15461603
}
15471604
// no matches found against the list!
15481605
return false;
15491606
}
15501607

1551-
//no ecclist system property, so use our own list.
1552-
return (number.startsWith("112") || number.startsWith("911"));
1608+
// No ecclist system property, so use our own list.
1609+
if (useExactMatch) {
1610+
return (number.equals("112") || number.equals("911"));
1611+
} else {
1612+
return (number.startsWith("112") || number.startsWith("911"));
1613+
}
15531614
}
15541615

15551616
/**
@@ -1559,31 +1620,81 @@ public static boolean isEmergencyNumber(String number) {
15591620
* @param defaultCountryIso the specific country which the number should be checked against
15601621
* @return if the number is an emergency number for the specific country, then return true,
15611622
* otherwise false
1623+
*
15621624
* @hide
15631625
*/
15641626
public static boolean isEmergencyNumber(String number, String defaultCountryIso) {
1565-
PhoneNumberUtil util = PhoneNumberUtil.getInstance();
1566-
try {
1567-
PhoneNumber pn = util.parse(number, defaultCountryIso);
1568-
// libphonenumber guarantees short numbers such as emergency numbers are classified as
1569-
// invalid. Therefore, if the number passes the validation test, we believe it is not an
1570-
// emergency number.
1571-
// TODO: Compare against a list of country-specific known emergency numbers instead, once
1572-
// that has been collected.
1573-
if (util.isValidNumber(pn)) {
1574-
return false;
1575-
} else if ("BR".equalsIgnoreCase(defaultCountryIso) && number.length() >= 8) {
1576-
// This is to prevent Brazilian local numbers which start with 911 being incorrectly
1577-
// classified as emergency numbers. 911 is not an emergency number in Brazil; it is also
1578-
// not possible to append additional digits to an emergency number to dial the number in
1579-
// Brazil - it won't connect.
1580-
// TODO: Clean this up once a list of country-specific known emergency numbers is
1581-
// collected.
1582-
return false;
1583-
}
1584-
} catch (NumberParseException e) {
1585-
}
1586-
return isEmergencyNumber(number);
1627+
return isEmergencyNumberInternal(number,
1628+
defaultCountryIso,
1629+
true /* useExactMatch */);
1630+
}
1631+
1632+
/**
1633+
* Checks if a given number might *potentially* result in a call to an
1634+
* emergency service, for a specific country.
1635+
*
1636+
* Specifically, this method will return true if the specified number
1637+
* is an emergency number in the specified country, *or* if the number
1638+
* simply starts with the same digits as any emergency number for that
1639+
* country.
1640+
*
1641+
* This method is intended for internal use by the phone app when
1642+
* deciding whether to allow ACTION_CALL intents from 3rd party apps
1643+
* (where we're required to *not* allow emergency calls to be placed.)
1644+
*
1645+
* @param number the number to look up.
1646+
* @param defaultCountryIso the specific country which the number should be checked against
1647+
* @return true if the number is an emergency number for the specific
1648+
* country, *or* if the number starts with the same digits as
1649+
* any of those emergency numbers.
1650+
*
1651+
* @hide
1652+
*/
1653+
public static boolean isPotentialEmergencyNumber(String number, String defaultCountryIso) {
1654+
return isEmergencyNumberInternal(number,
1655+
defaultCountryIso,
1656+
false /* useExactMatch */);
1657+
}
1658+
1659+
/**
1660+
* Helper function for isEmergencyNumber(String, String) and
1661+
* isPotentialEmergencyNumber(String, String).
1662+
*
1663+
* @param number the number to look up.
1664+
* @param defaultCountryIso the specific country which the number should be checked against
1665+
* @param useExactMatch if true, consider a number to be an emergency
1666+
* number only if it *exactly* matches a number listed in
1667+
* the RIL / SIM. If false, a number is considered to be an
1668+
* emergency number if it simply starts with the same digits
1669+
* as any of the emergency numbers listed in the RIL / SIM.
1670+
*
1671+
* @return true if the number is an emergency number for the specified country.
1672+
*/
1673+
private static boolean isEmergencyNumberInternal(String number,
1674+
String defaultCountryIso,
1675+
boolean useExactMatch) {
1676+
PhoneNumberUtil util = PhoneNumberUtil.getInstance();
1677+
try {
1678+
PhoneNumber pn = util.parse(number, defaultCountryIso);
1679+
// libphonenumber guarantees short numbers such as emergency numbers are classified as
1680+
// invalid. Therefore, if the number passes the validation test, we believe it is not an
1681+
// emergency number.
1682+
// TODO: Compare against a list of country-specific known emergency numbers instead, once
1683+
// that has been collected.
1684+
if (util.isValidNumber(pn)) {
1685+
return false;
1686+
} else if ("BR".equalsIgnoreCase(defaultCountryIso) && number.length() >= 8) {
1687+
// This is to prevent Brazilian local numbers which start with 911 being incorrectly
1688+
// classified as emergency numbers. 911 is not an emergency number in Brazil; it is also
1689+
// not possible to append additional digits to an emergency number to dial the number in
1690+
// Brazil - it won't connect.
1691+
// TODO: Clean this up once a list of country-specific known emergency numbers is
1692+
// collected.
1693+
return false;
1694+
}
1695+
} catch (NumberParseException e) {
1696+
}
1697+
return isEmergencyNumberInternal(number, useExactMatch);
15871698
}
15881699

15891700
/**
@@ -1592,12 +1703,66 @@ public static boolean isEmergencyNumber(String number, String defaultCountryIso)
15921703
*
15931704
* @param number the number to look up.
15941705
* @param context the specific context which the number should be checked against
1595-
* @return if a phone number is an emergency number for a local country, based on the
1596-
* CountryDetector.
1706+
* @return true if the specified number is an emergency number for a local country, based on the
1707+
* CountryDetector.
1708+
*
15971709
* @see android.location.CountryDetector
15981710
* @hide
15991711
*/
16001712
public static boolean isLocalEmergencyNumber(String number, Context context) {
1713+
return isLocalEmergencyNumberInternal(number,
1714+
context,
1715+
true /* useExactMatch */);
1716+
}
1717+
1718+
/**
1719+
* Checks if a given number might *potentially* result in a call to an
1720+
* emergency service, for the country that the user is in. The current
1721+
* country is determined using the CountryDetector.
1722+
*
1723+
* Specifically, this method will return true if the specified number
1724+
* is an emergency number in the current country, *or* if the number
1725+
* simply starts with the same digits as any emergency number for the
1726+
* current country.
1727+
*
1728+
* This method is intended for internal use by the phone app when
1729+
* deciding whether to allow ACTION_CALL intents from 3rd party apps
1730+
* (where we're required to *not* allow emergency calls to be placed.)
1731+
*
1732+
* @param number the number to look up.
1733+
* @param context the specific context which the number should be checked against
1734+
* @return true if the specified number is an emergency number for a local country, based on the
1735+
* CountryDetector.
1736+
*
1737+
* @see android.location.CountryDetector
1738+
* @hide
1739+
*/
1740+
public static boolean isPotentialLocalEmergencyNumber(String number, Context context) {
1741+
return isLocalEmergencyNumberInternal(number,
1742+
context,
1743+
false /* useExactMatch */);
1744+
}
1745+
1746+
/**
1747+
* Helper function for isLocalEmergencyNumber() and
1748+
* isPotentialLocalEmergencyNumber().
1749+
*
1750+
* @param number the number to look up.
1751+
* @param context the specific context which the number should be checked against
1752+
* @param useExactMatch if true, consider a number to be an emergency
1753+
* number only if it *exactly* matches a number listed in
1754+
* the RIL / SIM. If false, a number is considered to be an
1755+
* emergency number if it simply starts with the same digits
1756+
* as any of the emergency numbers listed in the RIL / SIM.
1757+
*
1758+
* @return true if the specified number is an emergency number for a
1759+
* local country, based on the CountryDetector.
1760+
*
1761+
* @see android.location.CountryDetector
1762+
*/
1763+
private static boolean isLocalEmergencyNumberInternal(String number,
1764+
Context context,
1765+
boolean useExactMatch) {
16011766
String countryIso;
16021767
CountryDetector detector = (CountryDetector) context.getSystemService(
16031768
Context.COUNTRY_DETECTOR);
@@ -1609,7 +1774,7 @@ public static boolean isLocalEmergencyNumber(String number, Context context) {
16091774
Log.w(LOG_TAG, "No CountryDetector; falling back to countryIso based on locale: "
16101775
+ countryIso);
16111776
}
1612-
return isEmergencyNumber(number, countryIso);
1777+
return isEmergencyNumberInternal(number, countryIso, useExactMatch);
16131778
}
16141779

16151780
/**

telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -550,21 +550,51 @@ public void testFormatDailabeNumber() {
550550
}
551551
@SmallTest
552552
public void testIsEmergencyNumber() {
553-
assertTrue(PhoneNumberUtils.isEmergencyNumber("911", "US"));
554-
assertTrue(PhoneNumberUtils.isEmergencyNumber("112", "US"));
555-
// The next two numbers are not valid phone numbers in the US, but can be used to trick the
556-
// system to dial 911 and 112, which are emergency numbers in the US. For the purpose of
557-
// addressing that, they are also classified as emergency numbers in the US.
558-
assertTrue(PhoneNumberUtils.isEmergencyNumber("91112345", "US"));
559-
assertTrue(PhoneNumberUtils.isEmergencyNumber("11212345", "US"));
560-
// A valid mobile phone number from Singapore shouldn't be classified as an emergency number
561-
// in Singapore, as 911 is not an emergency number there.
562-
assertFalse(PhoneNumberUtils.isEmergencyNumber("91121234", "SG"));
563-
// A valid fixed-line phone number from Brazil shouldn't be classified as an emergency number
564-
// in Brazil, as 112 is not an emergency number there.
565-
assertFalse(PhoneNumberUtils.isEmergencyNumber("1121234567", "BR"));
566-
// A valid local phone number from Brazil shouldn't be classified as an emergency number in
567-
// Brazil.
568-
assertFalse(PhoneNumberUtils.isEmergencyNumber("91112345", "BR"));
553+
// There are two parallel sets of tests here: one for the
554+
// regular isEmergencyNumber() method, and the other for
555+
// isPotentialEmergencyNumber().
556+
//
557+
// (The difference is that isEmergencyNumber() will return true
558+
// only if the specified number exactly matches an actual
559+
// emergency number, but isPotentialEmergencyNumber() will
560+
// return true if the specified number simply starts with the
561+
// same digits as any actual emergency number.)
562+
563+
// Tests for isEmergencyNumber():
564+
assertTrue(PhoneNumberUtils.isEmergencyNumber("911", "US"));
565+
assertTrue(PhoneNumberUtils.isEmergencyNumber("112", "US"));
566+
// The next two numbers are not valid phone numbers in the US,
567+
// so do not count as emergency numbers (but they *are* "potential"
568+
// emergency numbers; see below.)
569+
assertFalse(PhoneNumberUtils.isEmergencyNumber("91112345", "US"));
570+
assertFalse(PhoneNumberUtils.isEmergencyNumber("11212345", "US"));
571+
// A valid mobile phone number from Singapore shouldn't be classified as an emergency number
572+
// in Singapore, as 911 is not an emergency number there.
573+
assertFalse(PhoneNumberUtils.isEmergencyNumber("91121234", "SG"));
574+
// A valid fixed-line phone number from Brazil shouldn't be classified as an emergency number
575+
// in Brazil, as 112 is not an emergency number there.
576+
assertFalse(PhoneNumberUtils.isEmergencyNumber("1121234567", "BR"));
577+
// A valid local phone number from Brazil shouldn't be classified as an emergency number in
578+
// Brazil.
579+
assertFalse(PhoneNumberUtils.isEmergencyNumber("91112345", "BR"));
580+
581+
// Tests for isPotentialEmergencyNumber():
582+
// These first two are obviously emergency numbers:
583+
assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("911", "US"));
584+
assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("112", "US"));
585+
// The next two numbers are not valid phone numbers in the US, but can be used to trick the
586+
// system to dial 911 and 112, which are emergency numbers in the US. For the purpose of
587+
// addressing that, they are also classified as "potential" emergency numbers in the US.
588+
assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("91112345", "US"));
589+
assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("11212345", "US"));
590+
// A valid mobile phone number from Singapore shouldn't be classified as an emergency number
591+
// in Singapore, as 911 is not an emergency number there.
592+
assertFalse(PhoneNumberUtils.isPotentialEmergencyNumber("91121234", "SG"));
593+
// A valid fixed-line phone number from Brazil shouldn't be classified as an emergency number
594+
// in Brazil, as 112 is not an emergency number there.
595+
assertFalse(PhoneNumberUtils.isPotentialEmergencyNumber("1121234567", "BR"));
596+
// A valid local phone number from Brazil shouldn't be classified as an emergency number in
597+
// Brazil.
598+
assertFalse(PhoneNumberUtils.isPotentialEmergencyNumber("91112345", "BR"));
569599
}
570600
}

0 commit comments

Comments
 (0)