release-request-108343c4-ad88-44f9-aaa2-24d8b8a5c176-for-git_oc-mr1-release-4321077 snap-temp-L97000000100182150

Change-Id: I5f0732bd55bc68ee5c727a92f4cc3e800f9096ed
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
index f85114b..c19c28b 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
@@ -117,6 +117,10 @@
         SharedPreferences getDefaultSharedPreferences(Context context);
     }
 
+    public interface PhoneNumberUtilsProxy {
+        boolean isEmergencyNumber(String number);
+    }
+
     private static final boolean DBG = true;
 
     // When true, dumps the state of ImsPhoneCallTracker after changes to foreground and background
@@ -610,6 +614,14 @@
         return PreferenceManager.getDefaultSharedPreferences(context);
     };
 
+    /**
+     * Default implementation for determining if a number is an emergency number.  Uses the real
+     * PhoneNumberUtils.
+     */
+    private PhoneNumberUtilsProxy mPhoneNumberUtilsProxy = (String string) -> {
+        return PhoneNumberUtils.isEmergencyNumber(string);
+    };
+
     // Callback fires when ImsManager MMTel Feature changes state
     private ImsServiceProxy.INotifyStatusChanged mNotifyStatusChangedCallback = () -> {
         try {
@@ -700,6 +712,15 @@
         mSharedPreferenceProxy = sharedPreferenceProxy;
     }
 
+    /**
+     * Test-only method used to mock out access to the phone number utils class.
+     * @param phoneNumberUtilsProxy
+     */
+    @VisibleForTesting
+    public void setPhoneNumberUtilsProxy(PhoneNumberUtilsProxy phoneNumberUtilsProxy) {
+        mPhoneNumberUtilsProxy = phoneNumberUtilsProxy;
+    }
+
     private int getPackageUid(Context context, String pkg) {
         if (pkg == null) {
             return NetworkStats.UID_ALL;
@@ -836,9 +857,13 @@
     dial(String dialString, int clirMode, int videoState, Bundle intentExtras)
             throws CallStateException {
         boolean isPhoneInEcmMode = isPhoneInEcbMode();
-        boolean isEmergencyNumber = PhoneNumberUtils.isEmergencyNumber(dialString);
+        boolean isEmergencyNumber = mPhoneNumberUtilsProxy.isEmergencyNumber(dialString);
 
         if (DBG) log("dial clirMode=" + clirMode);
+        if (isEmergencyNumber) {
+            clirMode = CommandsInterface.CLIR_SUPPRESSION;
+            if (DBG) log("dial emergency call, set clirModIe=" + clirMode);
+        }
 
         // note that this triggers call state changed notif
         clearDisconnected();
@@ -1044,7 +1069,7 @@
 
         // Always unmute when initiating a new call
         setMute(false);
-        int serviceType = PhoneNumberUtils.isEmergencyNumber(conn.getAddress()) ?
+        int serviceType = mPhoneNumberUtilsProxy.isEmergencyNumber(conn.getAddress()) ?
                 ImsCallProfile.SERVICE_TYPE_EMERGENCY : ImsCallProfile.SERVICE_TYPE_NORMAL;
         int callType = ImsCallProfile.getCallTypeFromVideoState(videoState);
         //TODO(vt): Is this sufficient?  At what point do we know the video state of the call?
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
index 2c0478b..989cd64 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
@@ -380,6 +380,45 @@
         assertEquals("clir_key0", mStringCaptor.getValue());
     }
 
+    /**
+     * Ensures for an emergency call that the dial method will default the CLIR to
+     * {@link CommandsInterface#CLIR_SUPPRESSION}, ensuring the caller's ID is shown.
+     */
+    @Test
+    @SmallTest
+    public void testEmergencyDialSuppressClir() {
+        mCTUT.setSharedPreferenceProxy((Context context) -> {
+            return mSharedPreferences;
+        });
+        // Mock implementation of phone number utils treats everything as an emergency.
+        mCTUT.setPhoneNumberUtilsProxy((String string) -> {
+            return true;
+        });
+        // Set preference to hide caller ID.
+        ArgumentCaptor<String> stringCaptor = ArgumentCaptor.forClass(String.class);
+        doReturn(CommandsInterface.CLIR_INVOCATION).when(mSharedPreferences).getInt(
+                stringCaptor.capture(), anyInt());
+
+        try {
+            mCTUT.dial("+17005554141", VideoProfile.STATE_AUDIO_ONLY, null);
+
+            ArgumentCaptor<ImsCallProfile> profileCaptor = ArgumentCaptor.forClass(
+                    ImsCallProfile.class);
+            verify(mImsManager, times(1)).makeCall(eq(0), eq(mImsCallProfile),
+                    eq(new String[]{"+17005554141"}), (ImsCall.Listener) any());
+
+            // Because this is an emergency call, we expect caller id to be visible now.
+            verify(mImsCallProfile).setCallExtraInt(ImsCallProfile.EXTRA_OIR,
+                    CommandsInterface.CLIR_SUPPRESSION);
+        } catch (CallStateException cse) {
+            cse.printStackTrace();
+            Assert.fail("unexpected exception thrown" + cse.getMessage());
+        } catch (ImsException ie) {
+            ie.printStackTrace();
+            Assert.fail("unexpected exception thrown" + ie.getMessage());
+        }
+    }
+
     @FlakyTest
     @Ignore
     @Test