Improve outgoing call UI responsiveness

* Send call extras in a bundle to the service when binding. This
provides information about the call so that the incall-service can
setup its UI immediately before the rest of Telecom is done.

* Move outgoing call flow to always go through the CallReceiver.
This allows CallActivity to finish and not block ActivityManager by
remaining as the foreground activity.

Bug: 18373617

Change-Id: I75ca3b12ce1b0db91bd05f3c77cad31f78ca8ebd
diff --git a/src/com/android/server/telecom/CallActivity.java b/src/com/android/server/telecom/CallActivity.java
index 0d57b54..5ce0eb7 100644
--- a/src/com/android/server/telecom/CallActivity.java
+++ b/src/com/android/server/telecom/CallActivity.java
@@ -124,13 +124,7 @@
 
         intent.putExtra(CallReceiver.KEY_IS_DEFAULT_DIALER, isDefaultDialer());
 
-        if (UserHandle.myUserId() == UserHandle.USER_OWNER) {
-            Trace.beginSection("processOutgoingCallIntent");
-            CallReceiver.processOutgoingCallIntent(getApplicationContext(), intent);
-            Trace.endSection();
-        } else {
-            sendBroadcastToReceiver(intent, false /* isIncoming */);
-        }
+        sendBroadcastToReceiver(intent);
     }
 
     private boolean isDefaultDialer() {
@@ -159,11 +153,11 @@
     /**
      * Trampolines the intent to the broadcast receiver that runs only as the primary user.
      */
-    private boolean sendBroadcastToReceiver(Intent intent, boolean incoming) {
-        intent.putExtra(CallReceiver.KEY_IS_INCOMING_CALL, incoming);
+    private boolean sendBroadcastToReceiver(Intent intent) {
+        intent.putExtra(CallReceiver.KEY_IS_INCOMING_CALL, false);
         intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         intent.setClass(this, CallReceiver.class);
-        Log.d(this, "Sending broadcast as user to CallReceiver- isIncoming: %s", incoming);
+        Log.d(this, "Sending broadcast as user to CallReceiver");
         sendBroadcastAsUser(intent, UserHandle.OWNER);
         return true;
     }
diff --git a/src/com/android/server/telecom/CallReceiver.java b/src/com/android/server/telecom/CallReceiver.java
index 8654b7f..27d4f51 100644
--- a/src/com/android/server/telecom/CallReceiver.java
+++ b/src/com/android/server/telecom/CallReceiver.java
@@ -5,6 +5,7 @@
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.Trace;
 import android.os.UserHandle;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
@@ -33,11 +34,13 @@
         final boolean isUnknownCall = intent.getBooleanExtra(KEY_IS_UNKNOWN_CALL, false);
         Log.i(this, "onReceive - isUnknownCall: %s", isUnknownCall);
 
+        Trace.beginSection("processNewCallCallIntent");
         if (isUnknownCall) {
             processUnknownCallIntent(intent);
         } else {
             processOutgoingCallIntent(context, intent);
         }
+        Trace.endSection();
     }
 
     /**
diff --git a/src/com/android/server/telecom/InCallController.java b/src/com/android/server/telecom/InCallController.java
index 4698c61..b77dd14 100644
--- a/src/com/android/server/telecom/InCallController.java
+++ b/src/com/android/server/telecom/InCallController.java
@@ -39,8 +39,6 @@
 import android.telecom.TelecomManager;
 import android.util.ArrayMap;
 
-
-
 // TODO: Needed for move to system service: import com.android.internal.R;
 import com.android.internal.telecom.IInCallService;
 import com.android.internal.util.IndentingPrintWriter;
@@ -154,7 +152,7 @@
     @Override
     public void onCallAdded(Call call) {
         if (mInCallServices.isEmpty()) {
-            bind();
+            bind(call);
         } else {
             Log.i(this, "onCallAdded: %s", call);
             // Track the call if we don't already know about it.
@@ -274,8 +272,10 @@
     /**
      * Binds to the in-call app if not already connected by binding directly to the saved
      * component name of the {@link IInCallService} implementation.
+     *
+     * @param call The newly added call that triggered the binding to the in-call services.
      */
-    private void bind() {
+    private void bind(Call call) {
         ThreadUtil.checkOnMainThread();
         if (mInCallServices.isEmpty()) {
             PackageManager packageManager = mContext.getPackageManager();
@@ -316,9 +316,19 @@
                         Intent intent = new Intent(InCallService.SERVICE_INTERFACE);
                         intent.setComponent(componentName);
 
-                        final int bindFlags = mInCallComponentName.equals(componentName)
-                                ? Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT
-                                : Context.BIND_AUTO_CREATE;
+                        final int bindFlags;
+                        if (mInCallComponentName.equals(componentName)) {
+                            bindFlags = Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT;
+                            if (!call.isIncoming()) {
+                                intent.putExtra(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS,
+                                        call.getExtras());
+                                intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
+                                        call.getTargetPhoneAccount());
+                            }
+                        } else {
+                            bindFlags = Context.BIND_AUTO_CREATE;
+                        }
+
                         if (mContext.bindServiceAsUser(intent, inCallServiceConnection, bindFlags,
                                 UserHandle.CURRENT)) {
                             mServiceConnections.put(componentName, inCallServiceConnection);
diff --git a/src/com/android/server/telecom/Timeouts.java b/src/com/android/server/telecom/Timeouts.java
index 869e98a..47c4224 100644
--- a/src/com/android/server/telecom/Timeouts.java
+++ b/src/com/android/server/telecom/Timeouts.java
@@ -60,6 +60,6 @@
      * in-call UI.
      */
     public static long getNewOutgoingCallCancelMillis(ContentResolver contentResolver) {
-        return get(contentResolver, "new_outgoing_call_cancel_ms", 200L);
+        return get(contentResolver, "new_outgoing_call_cancel_ms", 300L);
     }
 }
diff --git a/tests/src/com/android/server/telecom/testapps/CallServiceNotifier.java b/tests/src/com/android/server/telecom/testapps/CallServiceNotifier.java
index 835863f..23e8222 100644
--- a/tests/src/com/android/server/telecom/testapps/CallServiceNotifier.java
+++ b/tests/src/com/android/server/telecom/testapps/CallServiceNotifier.java
@@ -111,6 +111,7 @@
                 .setSubscriptionAddress(Uri.parse("tel:555-TEST"))
                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
                 .setIcon(context, R.drawable.stat_sys_phone_call, Color.RED)
+                .setHighlightColor(Color.RED)
                 .setShortDescription("a short description for the call provider")
                 .setSupportedUriSchemes(Arrays.asList("tel"))
                 .build());
@@ -125,6 +126,7 @@
                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
                         PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)
                 .setIcon(context, R.drawable.stat_sys_phone_call, Color.GREEN)
+                .setHighlightColor(Color.GREEN)
                 .setShortDescription("a short description for the sim subscription")
                 .build());