Merge "Check user restrictions during incoming calls." into pi-dev
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index e2afb4c..8b3e634 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -45,10 +45,10 @@
     <string name="no_vm_number" msgid="4164780423805688336">"Número correio de voz ausente"</string>
     <string name="no_vm_number_msg" msgid="1300729501030053828">"Não há um número correio de voz armazenado no cartão SIM."</string>
     <string name="add_vm_number_str" msgid="4676479471644687453">"Adicionar número"</string>
-    <string name="change_default_dialer_dialog_title" msgid="9101655962941740507">"Usar o <xliff:g id="NEW_APP">%s</xliff:g> como seu aplicativo de smartphone padrão?"</string>
+    <string name="change_default_dialer_dialog_title" msgid="9101655962941740507">"Usar o <xliff:g id="NEW_APP">%s</xliff:g> como seu app de telefone padrão?"</string>
     <string name="change_default_dialer_dialog_affirmative" msgid="8606546663509166276">"Definir padrão"</string>
     <string name="change_default_dialer_dialog_negative" msgid="9078144617060173845">"Cancelar"</string>
-    <string name="change_default_dialer_warning_message" msgid="1417671460801684999">"O <xliff:g id="NEW_APP">%s</xliff:g> poderá ligar e controlar todos os aspectos das chamadas. Defina como aplicativo de smartphone padrão somente aqueles em que você confia."</string>
+    <string name="change_default_dialer_warning_message" msgid="1417671460801684999">"O <xliff:g id="NEW_APP">%s</xliff:g> poderá ligar e controlar todos os aspectos das chamadas. Defina como aplicativo Telefone padrão somente aqueles em que você confia."</string>
     <string name="blocked_numbers" msgid="2751843139572970579">"Números bloqueados"</string>
     <string name="blocked_numbers_msg" msgid="1045015186124965643">"Você não receberá chamadas nem mensagens de texto dos números bloqueados."</string>
     <string name="block_number" msgid="1101252256321306179">"Adicionar um número"</string>
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index 6f1693a..b5e2958 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -1172,6 +1172,12 @@
             return false;
         }
 
+        if (!PhoneAccount.SCHEME_SIP.equals(getHandle().getScheme()) &&
+                !PhoneAccount.SCHEME_TEL.equals(getHandle().getScheme())) {
+            // Can't log schemes other than SIP or TEL for now.
+            return false;
+        }
+
         return phoneAccount.getExtras() != null && phoneAccount.getExtras().getBoolean(
                 PhoneAccount.EXTRA_LOG_SELF_MANAGED_CALLS, false);
     }
diff --git a/src/com/android/server/telecom/CallIntentProcessor.java b/src/com/android/server/telecom/CallIntentProcessor.java
index d90cba4..ff3b7b2 100644
--- a/src/com/android/server/telecom/CallIntentProcessor.java
+++ b/src/com/android/server/telecom/CallIntentProcessor.java
@@ -101,9 +101,9 @@
         String scheme = handle.getScheme();
         String uriString = handle.getSchemeSpecificPart();
 
-        if (!PhoneAccount.SCHEME_VOICEMAIL.equals(scheme)) {
-            handle = Uri.fromParts(PhoneNumberUtils.isUriNumber(uriString) ?
-                    PhoneAccount.SCHEME_SIP : PhoneAccount.SCHEME_TEL, uriString, null);
+        // Ensure sip URIs dialed using TEL scheme get converted to SIP scheme.
+        if (PhoneAccount.SCHEME_TEL.equals(scheme) && PhoneNumberUtils.isUriNumber(uriString)) {
+            handle = Uri.fromParts(PhoneAccount.SCHEME_SIP, uriString, null);
         }
 
         PhoneAccountHandle phoneAccountHandle = intent.getParcelableExtra(
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 9c8dbf3..099e6d3 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -1827,8 +1827,8 @@
     }
 
     private boolean isRttSettingOn() {
-        return Settings.System.getInt(mContext.getContentResolver(),
-                Settings.System.RTT_CALLING_MODE, 0) != 0;
+        return Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.RTT_CALLING_MODE, 0) != 0;
     }
 
     void phoneAccountSelected(Call call, PhoneAccountHandle account, boolean setDefault) {
diff --git a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
index a7e21ad..3797c68 100644
--- a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
+++ b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
@@ -144,6 +144,9 @@
                         return;
                     }
 
+                    // TODO: Remove the assumption that phone numbers are either SIP or TEL.
+                    // This does not impact self-managed ConnectionServices as they do not use the
+                    // NewOutgoingCallIntentBroadcaster.
                     Uri resultHandleUri = Uri.fromParts(
                             mPhoneNumberUtilsAdapter.isUriNumber(resultNumber) ?
                                     PhoneAccount.SCHEME_SIP : PhoneAccount.SCHEME_TEL,
@@ -219,73 +222,88 @@
             }
         }
 
-        String number = mPhoneNumberUtilsAdapter.getNumberFromIntent(intent, mContext);
-        if (TextUtils.isEmpty(number)) {
-            Log.w(this, "Empty number obtained from the call intent.");
-            return DisconnectCause.NO_PHONE_NUMBER_SUPPLIED;
-        }
-
-        boolean isUriNumber = mPhoneNumberUtilsAdapter.isUriNumber(number);
-        if (!isUriNumber) {
-            number = mPhoneNumberUtilsAdapter.convertKeypadLettersToDigits(number);
-            number = mPhoneNumberUtilsAdapter.stripSeparators(number);
-        }
-
-        final boolean isPotentialEmergencyNumber = isPotentialEmergencyNumber(number);
-        Log.v(this, "isPotentialEmergencyNumber = %s", isPotentialEmergencyNumber);
-
-        rewriteCallIntentAction(intent, isPotentialEmergencyNumber);
-        action = intent.getAction();
-        // True for certain types of numbers that are not intended to be intercepted or modified
-        // by third parties (e.g. emergency numbers).
-        boolean callImmediately = false;
-
-        if (Intent.ACTION_CALL.equals(action)) {
-            if (isPotentialEmergencyNumber) {
-                if (!mIsDefaultOrSystemPhoneApp) {
-                    Log.w(this, "Cannot call potential emergency number %s with CALL Intent %s "
-                            + "unless caller is system or default dialer.", number, intent);
-                    launchSystemDialer(intent.getData());
-                    return DisconnectCause.OUTGOING_CANCELED;
-                } else {
-                    callImmediately = true;
-                }
-            }
-        } else if (Intent.ACTION_CALL_EMERGENCY.equals(action)) {
-            if (!isPotentialEmergencyNumber) {
-                Log.w(this, "Cannot call non-potential-emergency number %s with EMERGENCY_CALL "
-                        + "Intent %s.", number, intent);
-                return DisconnectCause.OUTGOING_CANCELED;
-            }
-            callImmediately = true;
-        } else {
-            Log.w(this, "Unhandled Intent %s. Ignoring and not placing call.", intent);
-            return DisconnectCause.INVALID_NUMBER;
-        }
-
-        // True for all managed calls, false for self-managed calls.
-        boolean sendNewOutgoingCallBroadcast = true;
         PhoneAccountHandle targetPhoneAccount = mIntent.getParcelableExtra(
                 TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE);
+        boolean isSelfManaged = false;
         if (targetPhoneAccount != null) {
             PhoneAccount phoneAccount =
                     mCallsManager.getPhoneAccountRegistrar().getPhoneAccountUnchecked(
                             targetPhoneAccount);
-            if (phoneAccount != null && phoneAccount.isSelfManaged()) {
-                callImmediately = true;
-                sendNewOutgoingCallBroadcast = false;
-                Log.i(this, "Skipping NewOutgoingCallBroadcast for self-managed call.");
+            if (phoneAccount != null) {
+                isSelfManaged = phoneAccount.isSelfManaged();
             }
         }
 
-        if (callImmediately) {
+        String number = "";
+        // True for certain types of numbers that are not intended to be intercepted or modified
+        // by third parties (e.g. emergency numbers).
+        boolean callImmediately = false;
+        // True for all managed calls, false for self-managed calls.
+        boolean sendNewOutgoingCallBroadcast = true;
+        Uri callingAddress = handle;
+
+        if (!isSelfManaged) {
+            // Placing a managed call
+            number = mPhoneNumberUtilsAdapter.getNumberFromIntent(intent, mContext);
+            if (TextUtils.isEmpty(number)) {
+                Log.w(this, "Empty number obtained from the call intent.");
+                return DisconnectCause.NO_PHONE_NUMBER_SUPPLIED;
+            }
+
+            // TODO: Cleanup this dialing code; it makes the assumption that we're dialing with a
+            // SIP or TEL URI.
+            boolean isUriNumber = mPhoneNumberUtilsAdapter.isUriNumber(number);
+            if (!isUriNumber) {
+                number = mPhoneNumberUtilsAdapter.convertKeypadLettersToDigits(number);
+                number = mPhoneNumberUtilsAdapter.stripSeparators(number);
+            }
+
+            final boolean isPotentialEmergencyNumber = isPotentialEmergencyNumber(number);
+            Log.v(this, "isPotentialEmergencyNumber = %s", isPotentialEmergencyNumber);
+
+            rewriteCallIntentAction(intent, isPotentialEmergencyNumber);
+            action = intent.getAction();
+
+            if (Intent.ACTION_CALL.equals(action)) {
+                if (isPotentialEmergencyNumber) {
+                    if (!mIsDefaultOrSystemPhoneApp) {
+                        Log.w(this, "Cannot call potential emergency number %s with CALL Intent %s "
+                                + "unless caller is system or default dialer.", number, intent);
+                        launchSystemDialer(intent.getData());
+                        return DisconnectCause.OUTGOING_CANCELED;
+                    } else {
+                        callImmediately = true;
+                    }
+                }
+            } else if (Intent.ACTION_CALL_EMERGENCY.equals(action)) {
+                if (!isPotentialEmergencyNumber) {
+                    Log.w(this, "Cannot call non-potential-emergency number %s with EMERGENCY_CALL "
+                            + "Intent %s.", number, intent);
+                    return DisconnectCause.OUTGOING_CANCELED;
+                }
+                callImmediately = true;
+            } else {
+                Log.w(this, "Unhandled Intent %s. Ignoring and not placing call.", intent);
+                return DisconnectCause.INVALID_NUMBER;
+            }
+
+            // TODO: Support dialing using URIs instead of just assuming SIP or TEL.
             String scheme = isUriNumber ? PhoneAccount.SCHEME_SIP : PhoneAccount.SCHEME_TEL;
+            callingAddress = Uri.fromParts(scheme, number, null);
+        } else {
+            // Self-managed call.
+            callImmediately = true;
+            sendNewOutgoingCallBroadcast = false;
+            Log.i(this, "Skipping NewOutgoingCallBroadcast for self-managed call.");
+        }
+
+        if (callImmediately) {
             boolean speakerphoneOn = mIntent.getBooleanExtra(
                     TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, false);
             int videoState = mIntent.getIntExtra(
                     TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE,
                     VideoProfile.STATE_AUDIO_ONLY);
-            placeOutgoingCallImmediately(mCall, Uri.fromParts(scheme, number, null), null,
+            placeOutgoingCallImmediately(mCall, callingAddress, null,
                     speakerphoneOn, videoState);
 
             // Don't return but instead continue and send the ACTION_NEW_OUTGOING_CALL broadcast
diff --git a/src/com/android/server/telecom/Ringer.java b/src/com/android/server/telecom/Ringer.java
index c4f9b63..1d27f45 100644
--- a/src/com/android/server/telecom/Ringer.java
+++ b/src/com/android/server/telecom/Ringer.java
@@ -18,6 +18,7 @@
 
 import android.app.Notification;
 import android.app.NotificationManager;
+import android.app.Person;
 import android.content.Context;
 import android.os.VibrationEffect;
 import android.telecom.Log;
@@ -279,8 +280,8 @@
                 (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
         final Bundle peopleExtras = new Bundle();
         if (contactUri != null) {
-            ArrayList<Notification.Person> personList = new ArrayList<>();
-            personList.add(new Notification.Person().setUri(contactUri.toString()));
+            ArrayList<Person> personList = new ArrayList<>();
+            personList.add(new Person.Builder().setUri(contactUri.toString()).build());
             peopleExtras.putParcelableArrayList(Notification.EXTRA_PEOPLE_LIST, personList);
         }
         return manager.matchesCallFilter(peopleExtras);
diff --git a/src/com/android/server/telecom/components/UserCallIntentProcessor.java b/src/com/android/server/telecom/components/UserCallIntentProcessor.java
index 38c14d7..1a76043 100644
--- a/src/com/android/server/telecom/components/UserCallIntentProcessor.java
+++ b/src/com/android/server/telecom/components/UserCallIntentProcessor.java
@@ -103,9 +103,9 @@
         String scheme = handle.getScheme();
         String uriString = handle.getSchemeSpecificPart();
 
-        if (!PhoneAccount.SCHEME_VOICEMAIL.equals(scheme)) {
-            handle = Uri.fromParts(PhoneNumberUtils.isUriNumber(uriString) ?
-                    PhoneAccount.SCHEME_SIP : PhoneAccount.SCHEME_TEL, uriString, null);
+        // Ensure sip URIs dialed using TEL scheme get converted to SIP scheme.
+        if (PhoneAccount.SCHEME_TEL.equals(scheme) && PhoneNumberUtils.isUriNumber(uriString)) {
+            handle = Uri.fromParts(PhoneAccount.SCHEME_SIP, uriString, null);
         }
 
         // Check DISALLOW_OUTGOING_CALLS restriction. Note: We are skipping this check in a managed
diff --git a/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java b/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
index ec80911..7fee263 100644
--- a/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
+++ b/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
@@ -583,6 +583,7 @@
                                     || TextUtils.isEmpty(handleString)) {
                                 handle = null;
                             } else {
+                                // TODO: Remove the assumption that numbers are SIP or TEL only.
                                 handle = Uri.fromParts(PhoneNumberUtils.isUriNumber(handleString) ?
                                         PhoneAccount.SCHEME_SIP : PhoneAccount.SCHEME_TEL,
                                                 handleString, null);
diff --git a/testapps/src/com/android/server/telecom/testapps/SelfManagedCallList.java b/testapps/src/com/android/server/telecom/testapps/SelfManagedCallList.java
index 8518adc..4b5fa57 100644
--- a/testapps/src/com/android/server/telecom/testapps/SelfManagedCallList.java
+++ b/testapps/src/com/android/server/telecom/testapps/SelfManagedCallList.java
@@ -48,6 +48,7 @@
     public static String SELF_MANAGED_ACCOUNT_2 = "2";
     public static String SELF_MANAGED_NAME_1 = "SuperCall";
     public static String SELF_MANAGED_NAME_2 = "Mega Call";
+    public static String CUSTOM_URI_SCHEME = "custom";
 
     private static SelfManagedCallList sInstance;
     private static ComponentName COMPONENT_NAME = new ComponentName(
@@ -112,6 +113,7 @@
         PhoneAccount.Builder builder = PhoneAccount.builder(handle, name)
                 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
                 .addSupportedUriScheme(PhoneAccount.SCHEME_SIP)
+                .addSupportedUriScheme(CUSTOM_URI_SCHEME)
                 .setAddress(address)
                 .setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED |
                         PhoneAccount.CAPABILITY_VIDEO_CALLING |
diff --git a/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java b/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
index 9cc2b87..01d312b 100644
--- a/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
+++ b/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
@@ -437,6 +437,7 @@
         MockitoAnnotations.initMocks(this);
         when(mResources.getConfiguration()).thenReturn(mResourceConfiguration);
         when(mResources.getString(anyInt())).thenReturn("");
+        when(mResources.getStringArray(anyInt())).thenReturn(new String[0]);
         mResourceConfiguration.setLocale(Locale.TAIWAN);
 
         // TODO: Move into actual tests