Use isPotentialLocalEmergencyNumber() to enforce ACTION_CALL restriction

The framework PhoneNumberUtils class now provides a way to distinguish
between (a) numbers that are definitely emergency numbers, and (b) numbers
that *might* result in an emergency call being dialed, but aren't
specifically emergency numbers themselves.

Given that, we now use the new isPotentialLocalEmergencyNumber() API when
enforcing the restriction that 3rd party apps should not be allowed to
make emergency calls using the ACTION_CALL intent.  (This ensures that 3rd
party apps can't make emergency calls by passing in an "invalid" number
like "9111234" that isn't technically an emergency number but might still
result in an emergency call with some networks.)

Everywhere else in the app, though, we still use the original
isLocalEmergencyNumber() API, which now returns true only if the specified
number *exactly* matches a known emergency number.  This ensures that the
in-call UI will only display the "emergency call" state for numbers that are
*definitely* emergency numbers.  (See bug 5493790 for the full details.)

TESTED (on Prime-C):

- Call regular non-emergency numbers from the built-in dialer
  ==> calls succeed with no emergency-call specific behavior

- Call "911" from the built-in dialer
  ==> Call to 911 succeeds
  ==> In-call UI shows the "emergency call" state
  ==> We correctly disable "mute"
  ==> We correctly enter ECM

- Call "9111234567" from the built-in dialer
  ==> We allow the call to be placed
  ==> The call does not actually go through; you just hear a recorded
      message from Verizon saying "the call could not be completed"
      (although this behavior might be different on other networks)
  ==> The in-call UI does NOT show the "emergency call" state
  ==> We do not disable "mute"
  ==> We do not enter ECM

- use CallDialTest activity to fire off various ACTION_CALL intents
  (as if launched from a 3rd party app):
    "911"  ==> doesn't allow the call to be placed (brings up dialer instead)
    "9111234"  ==> doesn't allow the call to be placed (brings up dialer instead)
    "6502530000"  ==> call succeeds

Note: This change depends on
  Change-Id: Ic528cfcc555734cdaf4ca8a18a50199771ba49b1
in frameworks/base (which must be submitted first.)

Bug: 5493790
Change-Id: Ib949fea3c0ce6b341a90e617a03ba3f22c69018b
diff --git a/src/com/android/phone/CallController.java b/src/com/android/phone/CallController.java
index fd7c088..11f24ce 100644
--- a/src/com/android/phone/CallController.java
+++ b/src/com/android/phone/CallController.java
@@ -367,17 +367,25 @@
             return CallStatusCode.NO_PHONE_NUMBER_SUPPLIED;
         }
 
+
+        // Sanity-check that ACTION_CALL_EMERGENCY is used if and only if
+        // this is a call to an emergency number
+        // (This is just a sanity-check; this policy *should* really be
+        // enforced in OutgoingCallBroadcaster.onCreate(), which is the
+        // main entry point for the CALL and CALL_* intents.)
         boolean isEmergencyNumber = PhoneNumberUtils.isLocalEmergencyNumber(number, mApp);
+        boolean isPotentialEmergencyNumber =
+                PhoneNumberUtils.isPotentialLocalEmergencyNumber(number, mApp);
         boolean isEmergencyIntent = Intent.ACTION_CALL_EMERGENCY.equals(intent.getAction());
 
-        if (isEmergencyNumber && !isEmergencyIntent) {
+        if (isPotentialEmergencyNumber && !isEmergencyIntent) {
             Log.e(TAG, "Non-CALL_EMERGENCY Intent " + intent
-                    + " attempted to call emergency number " + number
+                    + " attempted to call potential emergency number " + number
                     + ".");
             return CallStatusCode.CALL_FAILED;
-        } else if (!isEmergencyNumber && isEmergencyIntent) {
+        } else if (!isPotentialEmergencyNumber && isEmergencyIntent) {
             Log.e(TAG, "Received CALL_EMERGENCY Intent " + intent
-                    + " with non-emergency number " + number
+                    + " with non-potential-emergency number " + number
                     + " -- failing call.");
             return CallStatusCode.CALL_FAILED;
         }
diff --git a/src/com/android/phone/OutgoingCallBroadcaster.java b/src/com/android/phone/OutgoingCallBroadcaster.java
index aaf32bb..0d7d1e6 100644
--- a/src/com/android/phone/OutgoingCallBroadcaster.java
+++ b/src/com/android/phone/OutgoingCallBroadcaster.java
@@ -168,7 +168,11 @@
                     && (app.phone.isOtaSpNumber(number))) {
                 if (DBG) Log.v(TAG, "Call is active, a 2nd OTA call cancelled -- returning.");
                 return;
-            } else if (PhoneNumberUtils.isLocalEmergencyNumber(number, context)) {
+            } else if (PhoneNumberUtils.isPotentialLocalEmergencyNumber(number, context)) {
+                // Just like 3rd-party apps aren't allowed to place emergency
+                // calls via the ACTION_CALL intent, we also don't allow 3rd
+                // party apps to use the NEW_OUTGOING_CALL broadcast to rewrite
+                // an outgoing call into an emergency number.
                 Log.w(TAG, "Cannot modify outgoing call to emergency number " + number + ".");
                 return;
             }
@@ -348,9 +352,11 @@
                 number = PhoneNumberUtils.stripSeparators(number);
             }
         }
-        final boolean emergencyNumber =
-                (number != null) && PhoneNumberUtils.isLocalEmergencyNumber(number, this);
 
+        // If true, this flag will indicate that the current call is a special kind
+        // of call (most likely an emergency number) that 3rd parties aren't allowed
+        // to intercept or affect in any way.  (In that case, we start the call
+        // immediately rather than going through the NEW_OUTGOING_CALL sequence.)
         boolean callNow;
 
         if (getClass().getName().equals(intent.getComponent().getClassName())) {
@@ -363,10 +369,36 @@
             }
         }
 
+        // Check whether or not this is an emergency number, in order to
+        // enforce the restriction that only the CALL_PRIVILEGED and
+        // CALL_EMERGENCY intents are allowed to make emergency calls.
+        //
+        // (Note that the ACTION_CALL check below depends on the result of
+        // isPotentialLocalEmergencyNumber() rather than just plain
+        // isLocalEmergencyNumber(), to be 100% certain that we *don't*
+        // allow 3rd party apps to make emergency calls by passing in an
+        // "invalid" number like "9111234" that isn't technically an
+        // emergency number but might still result in an emergency call
+        // with some networks.)
+        final boolean isExactEmergencyNumber =
+                (number != null) && PhoneNumberUtils.isLocalEmergencyNumber(number, this);
+        final boolean isPotentialEmergencyNumber =
+                (number != null) && PhoneNumberUtils.isPotentialLocalEmergencyNumber(number, this);
+        if (VDBG) {
+            Log.v(TAG, "- Checking restrictions for number '" + number + "':");
+            Log.v(TAG, "    isExactEmergencyNumber     = " + isExactEmergencyNumber);
+            Log.v(TAG, "    isPotentialEmergencyNumber = " + isPotentialEmergencyNumber);
+        }
+
         /* Change CALL_PRIVILEGED into CALL or CALL_EMERGENCY as needed. */
         // TODO: This code is redundant with some code in InCallScreen: refactor.
         if (Intent.ACTION_CALL_PRIVILEGED.equals(action)) {
-            action = emergencyNumber
+            // We're handling a CALL_PRIVILEGED intent, so we know this request came
+            // from a trusted source (like the built-in dialer.)  So even a number
+            // that's *potentially* an emergency number can safely be promoted to
+            // CALL_EMERGENCY (since we *should* allow you to dial "91112345" from
+            // the dialer if you really want to.)
+            action = isPotentialEmergencyNumber
                     ? Intent.ACTION_CALL_EMERGENCY
                     : Intent.ACTION_CALL;
             if (DBG) Log.v(TAG, "- updating action from CALL_PRIVILEGED to " + action);
@@ -374,9 +406,10 @@
         }
 
         if (Intent.ACTION_CALL.equals(action)) {
-            if (emergencyNumber) {
-                Log.w(TAG, "Cannot call emergency number " + number
-                        + " with CALL Intent " + intent + ".");
+            if (isPotentialEmergencyNumber) {
+                Log.w(TAG, "Cannot call potential emergency number '" + number
+                        + "' with CALL Intent " + intent + ".");
+                Log.i(TAG, "Launching default dialer instead...");
 
                 Intent invokeFrameworkDialer = new Intent();
 
@@ -403,8 +436,10 @@
             // above), or else it really is an CALL_EMERGENCY intent that
             // came directly from some other app (e.g. the EmergencyDialer
             // activity built in to the Phone app.)
-            if (!emergencyNumber) {
-                Log.w(TAG, "Cannot call non-emergency number " + number
+            // Make sure it's at least *possible* that this is really an
+            // emergency number.
+            if (!isPotentialEmergencyNumber) {
+                Log.w(TAG, "Cannot call non-potential-emergency number " + number
                         + " with EMERGENCY_CALL Intent " + intent + ".");
                 finish();
                 return;