Fix call redirection service issues.

1.
Pressing the "home" button or otherwise switching apps while the call
redirection dialog is showing puts the device in a bad state.  The dialog
can no longer be visited from the recents menu, and as such you end up
with a call stuck in a connecting state.  This prevents all future calls
from being placed until reboot.

To fix this, add an onStop handler which will ensure that redirection is
canceled if the user switches apps or hits the home button.

Also, fixed an invalid string which was causing a string formatting error
(too many %s'es).

2. Fix issue where emergency numbers were being routed to a call
redirection service.  These should NOT be.

Test: Place call with redirection app installed; cancel from dialog and
verify it cancels call.
Test: Place call with redirection app installed; place call using carrier
from dialog and verify it connects call via carrier.
Test: Place call with redirection app installed; place call using redir
app from dialog and verify it connects call via redirection app.
Test: Hit home to dismiss the dialog; verify call is canceled.
Test: Add test emergency number, verify can call emergency number
Fixes: 137223601
Fixes: 137315607
Change-Id: I7274bf5c34d5f119e011e6828b97ed2fe270c303
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index aa87c32..d6bd975 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -1841,7 +1841,7 @@
             mPendingUnredirectedOutgoingCallInfo.remove(callId);
         } else {
             Log.w(this, "processRedirectedOutgoingCallAfterUserInteraction for non-matched Call ID"
-                    + " %s with handle %s and phoneAccountHandle %s", callId);
+                    + " %s", callId);
         }
     }
 
diff --git a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
index 51ddd8e..7a641af 100644
--- a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
+++ b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
@@ -288,6 +288,7 @@
                     return result;
                 } else {
                     result.callImmediately = true;
+                    result.requestRedirection = false;
                 }
             }
         } else if (Intent.ACTION_CALL_EMERGENCY.equals(action)) {
@@ -298,6 +299,7 @@
                 return result;
             }
             result.callImmediately = true;
+            result.requestRedirection = false;
         } else {
             Log.w(this, "Unhandled Intent %s. Ignoring and not placing call.", intent);
             result.disconnectCause = DisconnectCause.INVALID_NUMBER;
diff --git a/src/com/android/server/telecom/ui/CallRedirectionConfirmDialogActivity.java b/src/com/android/server/telecom/ui/CallRedirectionConfirmDialogActivity.java
index 32b0960..0d3599e 100644
--- a/src/com/android/server/telecom/ui/CallRedirectionConfirmDialogActivity.java
+++ b/src/com/android/server/telecom/ui/CallRedirectionConfirmDialogActivity.java
@@ -43,19 +43,38 @@
     public static final String EXTRA_REDIRECTION_APP_NAME =
             "android.telecom.extra.REDIRECTION_APP_NAME";
 
+    private String mCallId;
+    private AlertDialog mConfirmDialog;
+    /**
+     * Tracks whether the activity has stopped due to a loss of focus (e.g. use hitting the home
+     * button) or whether its going to stop because a button in the dialog was pressed.
+     */
+    private boolean mHasLostFocus = true;
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         Log.i(this, "CallRedirectionConfirmDialogActivity onCreate.");
         final CharSequence redirectionAppName = getIntent().getStringExtra(
                 EXTRA_REDIRECTION_APP_NAME);
+        mCallId = getIntent().getStringExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID);
         showDialog(redirectionAppName);
     }
 
+    @Override
+    protected void onStop() {
+        super.onStop();
+        if (mHasLostFocus) {
+            Log.i(this, "onStop: dialog lost focus; canceling redirection for call %s", mCallId);
+            mConfirmDialog.dismiss();
+            cancelRedirection();
+        }
+    }
+
     private void showDialog(final CharSequence redirectionAppName) {
         Log.i(this, "showDialog: confirming redirection with %s", redirectionAppName);
 
-        final AlertDialog confirmDialog = new AlertDialog.Builder(this).create();
+        mConfirmDialog = new AlertDialog.Builder(this).create();
         LayoutInflater layoutInflater = LayoutInflater.from(this);
         View dialogView = layoutInflater.inflate(R.layout.call_redirection_confirm_dialog, null);
 
@@ -67,10 +86,10 @@
                         TelecomBroadcastIntentProcessor.ACTION_PLACE_UNREDIRECTED_CALL,
                         null, CallRedirectionConfirmDialogActivity.this,
                         TelecomBroadcastReceiver.class);
-                proceedWithoutRedirectedCall.putExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID,
-                        getIntent().getStringExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID));
+                proceedWithoutRedirectedCall.putExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID, mCallId);
                 sendBroadcast(proceedWithoutRedirectedCall);
-                confirmDialog.dismiss();
+                mConfirmDialog.dismiss();
+                mHasLostFocus = false;
                 finish();
             }
         });
@@ -86,10 +105,10 @@
                                 .ACTION_PLACE_REDIRECTED_CALL, null,
                         CallRedirectionConfirmDialogActivity.this,
                         TelecomBroadcastReceiver.class);
-                proceedWithRedirectedCall.putExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID,
-                        getIntent().getStringExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID));
+                proceedWithRedirectedCall.putExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID, mCallId);
                 sendBroadcast(proceedWithRedirectedCall);
-                confirmDialog.dismiss();
+                mConfirmDialog.dismiss();
+                mHasLostFocus = false;
                 finish();
             }
         });
@@ -101,36 +120,42 @@
                         TelecomBroadcastIntentProcessor.ACTION_CANCEL_REDIRECTED_CALL,
                         null, CallRedirectionConfirmDialogActivity.this,
                         TelecomBroadcastReceiver.class);
-                cancelRedirectedCall.putExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID,
-                        getIntent().getStringExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID));
+                cancelRedirectedCall.putExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID, mCallId);
                 sendBroadcast(cancelRedirectedCall);
-                confirmDialog.dismiss();
+                mConfirmDialog.dismiss();
+                mHasLostFocus = false;
                 finish();
             }
         });
 
-        confirmDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
+        mConfirmDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
             @Override
             public void onCancel(DialogInterface dialog) {
-                Intent cancelRedirectedCall = new Intent(
-                        TelecomBroadcastIntentProcessor.ACTION_CANCEL_REDIRECTED_CALL,
-                        null, CallRedirectionConfirmDialogActivity.this,
-                        TelecomBroadcastReceiver.class);
-                cancelRedirectedCall.putExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID,
-                        getIntent().getStringExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID));
-                sendBroadcast(cancelRedirectedCall);
+                cancelRedirection();
                 dialog.dismiss();
+                mHasLostFocus = false;
                 finish();
             }
         });
 
-        confirmDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+        mConfirmDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
 
-        confirmDialog.setCancelable(false);
-        confirmDialog.setCanceledOnTouchOutside(false);
+        mConfirmDialog.setCancelable(false);
+        mConfirmDialog.setCanceledOnTouchOutside(false);
+        mConfirmDialog.setView(dialogView);
 
-        confirmDialog.setView(dialogView);
+        mConfirmDialog.show();
+    }
 
-        confirmDialog.show();
+    /**
+     * Signals to Telecom that redirection of the call is to be cancelled.
+     */
+    private void cancelRedirection() {
+        Intent cancelRedirectedCall = new Intent(
+                TelecomBroadcastIntentProcessor.ACTION_CANCEL_REDIRECTED_CALL,
+                null, CallRedirectionConfirmDialogActivity.this,
+                TelecomBroadcastReceiver.class);
+        cancelRedirectedCall.putExtra(EXTRA_REDIRECTION_OUTGOING_CALL_ID, mCallId);
+        sendBroadcast(cancelRedirectedCall);
     }
 }