Merge "Change UI to be consistency with dialer settings light M2 theme"
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index 628df84..84ceee6 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -254,7 +254,7 @@
     /**
      * The post-dial digits that were dialed after the network portion of the number
      */
-    private final String mPostDialDigits;
+    private String mPostDialDigits;
 
     /**
      * The secondary line number that an incoming call has been received on if the SIM subscription
@@ -1005,6 +1005,10 @@
         return mPostDialDigits;
     }
 
+    public void clearPostDialDigits() {
+        mPostDialDigits = null;
+    }
+
     public String getViaNumber() {
         return mViaNumber;
     }
diff --git a/src/com/android/server/telecom/CallAudioRouteStateMachine.java b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
index 69245da..dcf1b27 100644
--- a/src/com/android/server/telecom/CallAudioRouteStateMachine.java
+++ b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
@@ -154,7 +154,7 @@
     public static final int ACTIVE_FOCUS = 2;
     public static final int RINGING_FOCUS = 3;
 
-    /** Valid values for the argument for SWITCH_BASELINE_ROUTE */
+    /** Valid values for the first argument for SWITCH_BASELINE_ROUTE */
     public static final int NO_INCLUDE_BLUETOOTH_IN_BASELINE = 0;
     public static final int INCLUDE_BLUETOOTH_IN_BASELINE = 1;
 
@@ -352,7 +352,6 @@
         public void enter() {
             super.enter();
             setSpeakerphoneOn(false);
-            setBluetoothOff();
             CallAudioState newState = new CallAudioState(mIsMuted, ROUTE_EARPIECE,
                     mAvailableRoutes, null,
                     mBluetoothRouteManager.getConnectedDevices());
@@ -547,7 +546,6 @@
         public void enter() {
             super.enter();
             setSpeakerphoneOn(false);
-            setBluetoothOff();
             CallAudioState newState = new CallAudioState(mIsMuted, ROUTE_WIRED_HEADSET,
                     mAvailableRoutes, null, mBluetoothRouteManager.getConnectedDevices());
             setSystemAudioState(newState, true);
@@ -766,6 +764,32 @@
         }
 
         @Override
+        public void handleBtInitiatedDisconnect() {
+            // There's special-case state transitioning here -- if BT tells us that
+            // something got disconnected, we don't want to disconnect BT before
+            // transitioning, since BT might be trying to connect another device in the
+            // meantime.
+            int command = calculateBaselineRouteMessage(false, false);
+            switch (command) {
+                case SWITCH_EARPIECE:
+                    transitionTo(mActiveEarpieceRoute);
+                    break;
+                case SWITCH_HEADSET:
+                    transitionTo(mActiveHeadsetRoute);
+                    break;
+                case SWITCH_SPEAKER:
+                    transitionTo(mActiveSpeakerRoute);
+                    break;
+                default:
+                    Log.w(this, "Got unexpected code " + command + " when processing a"
+                            + " BT-initiated audio disconnect");
+                    // Some fallback logic to make sure we make it off the bluetooth route.
+                    super.handleBtInitiatedDisconnect();
+                    break;
+            }
+        }
+
+        @Override
         public boolean processMessage(Message msg) {
             if (super.processMessage(msg) == HANDLED) {
                 return HANDLED;
@@ -776,6 +800,7 @@
                     // fall through
                 case SWITCH_EARPIECE:
                     if ((mAvailableRoutes & ROUTE_EARPIECE) != 0) {
+                        setBluetoothOff();
                         transitionTo(mActiveEarpieceRoute);
                     } else {
                         Log.w(this, "Ignoring switch to earpiece command. Not available.");
@@ -799,6 +824,7 @@
                     // fall through
                 case SWITCH_HEADSET:
                     if ((mAvailableRoutes & ROUTE_WIRED_HEADSET) != 0) {
+                        setBluetoothOff();
                         transitionTo(mActiveHeadsetRoute);
                     } else {
                         Log.w(this, "Ignoring switch to headset command. Not available.");
@@ -808,6 +834,7 @@
                     mHasUserExplicitlyLeftBluetooth = true;
                     // fall through
                 case SWITCH_SPEAKER:
+                    setBluetoothOff();
                     transitionTo(mActiveSpeakerRoute);
                     return HANDLED;
                 case SWITCH_FOCUS:
@@ -822,7 +849,7 @@
                     }
                     return HANDLED;
                 case BT_AUDIO_DISCONNECTED:
-                    sendInternalMessage(SWITCH_BASELINE_ROUTE, NO_INCLUDE_BLUETOOTH_IN_BASELINE);
+                    handleBtInitiatedDisconnect();
                     return HANDLED;
                 default:
                     return NOT_HANDLED;
@@ -1000,6 +1027,10 @@
             return CallAudioState.ROUTE_BLUETOOTH;
         }
 
+        public void handleBtInitiatedDisconnect() {
+            sendInternalMessage(SWITCH_BASELINE_ROUTE, NO_INCLUDE_BLUETOOTH_IN_BASELINE);
+        }
+
         @Override
         public boolean processMessage(Message msg) {
             if (super.processMessage(msg) == HANDLED) {
@@ -1014,7 +1045,7 @@
                             + " have been null while we were in BT route.");
                     return HANDLED;
                 case BT_ACTIVE_DEVICE_GONE:
-                    sendInternalMessage(SWITCH_BASELINE_ROUTE, NO_INCLUDE_BLUETOOTH_IN_BASELINE);
+                    handleBtInitiatedDisconnect();
                     mWasOnSpeaker = false;
                     return HANDLED;
                 case DISCONNECT_WIRED_HEADSET:
@@ -1048,7 +1079,6 @@
             super.enter();
             mWasOnSpeaker = true;
             setSpeakerphoneOn(true);
-            setBluetoothOff();
             CallAudioState newState = new CallAudioState(mIsMuted, ROUTE_SPEAKER,
                     mAvailableRoutes, null, mBluetoothRouteManager.getConnectedDevices());
             setSystemAudioState(newState, true);
diff --git a/src/com/android/server/telecom/ConnectionServiceWrapper.java b/src/com/android/server/telecom/ConnectionServiceWrapper.java
index 90064cd..eb2e233 100644
--- a/src/com/android/server/telecom/ConnectionServiceWrapper.java
+++ b/src/com/android/server/telecom/ConnectionServiceWrapper.java
@@ -1662,6 +1662,14 @@
         if (connection.getState() == Connection.STATE_DISCONNECTED) {
             // A connection that begins in the DISCONNECTED state is an indication of
             // failure to connect; we handle all failures uniformly
+            Call foundCall = mCallIdMapper.getCall(callId);
+            if (foundCall != null) {
+                // The post-dial digits are created when the call is first created.  Normally
+                // the ConnectionService is responsible for stripping them from the address, but
+                // since a failed connection will not have done this, we could end up with duplicate
+                // post-dial digits.
+                foundCall.clearPostDialDigits();
+            }
             removeCall(callId, connection.getDisconnectCause());
         } else {
             // Successful connection
diff --git a/src/com/android/server/telecom/NuisanceCallReporter.java b/src/com/android/server/telecom/NuisanceCallReporter.java
index 064527b..4140a18 100644
--- a/src/com/android/server/telecom/NuisanceCallReporter.java
+++ b/src/com/android/server/telecom/NuisanceCallReporter.java
@@ -29,6 +29,7 @@
 import android.telecom.CallScreeningService;
 import android.telecom.Log;
 import android.telecom.PhoneAccountHandle;
+import android.text.TextUtils;
 
 import java.util.Arrays;
 
@@ -112,8 +113,9 @@
      * or rejected call.
      */
     private static final String NUMBER_WHERE_CLAUSE =
-            CallLog.Calls.CACHED_NORMALIZED_NUMBER + " = ? AND " + CallLog.Calls.TYPE
-                    + " IN (" + CallLog.Calls.INCOMING_TYPE + "," + CallLog.Calls.MISSED_TYPE + ","
+            "(" + CallLog.Calls.CACHED_NORMALIZED_NUMBER + " = ? OR "
+                    + CallLog.Calls.NUMBER + " = ?) AND " + CallLog.Calls.TYPE + " IN ("
+                    + CallLog.Calls.INCOMING_TYPE + "," + CallLog.Calls.MISSED_TYPE + ","
                     + CallLog.Calls.BLOCKED_TYPE + "," + CallLog.Calls.REJECTED_TYPE + ")";
 
     /**
@@ -169,7 +171,7 @@
 
     private void maybeSendNuisanceReport(@NonNull NuisanceReport nuisanceReport) {
         Uri callsUri = CallLog.Calls.CONTENT_URI;
-        if (mCurrentUserHandle == null) {
+        if (mCurrentUserHandle == null || nuisanceReport.handle == null) {
             return;
         }
 
@@ -178,13 +180,17 @@
 
         String normalizedNumber = mPhoneNumberUtilsProxy.formatNumberToE164(
                 nuisanceReport.handle.getSchemeSpecificPart());
-
+        if (TextUtils.isEmpty(normalizedNumber)) {
+            normalizedNumber = nuisanceReport.handle.getSchemeSpecificPart();
+        }
+        Log.d(this, "maybeSendNuisanceReport:  rawNumber=%s, number=%s, isNuisance=%b",
+                Log.piiHandle(nuisanceReport.handle), Log.piiHandle(normalizedNumber),
+                nuisanceReport.isNuisance);
         // Query the call log for the most recent information about this call.
         Cursor cursor = mContext.getContentResolver().query(callsUri, CALL_LOG_PROJECTION,
-                NUMBER_WHERE_CLAUSE, new String[] { normalizedNumber },
+                NUMBER_WHERE_CLAUSE, new String[] { normalizedNumber,
+                        nuisanceReport.handle.getSchemeSpecificPart() },
                 CallLog.Calls.DEFAULT_SORT_ORDER);
-        Log.d(this, "maybeSendNuisanceReport:  number=%s, isNuisance=%b",
-                Log.piiHandle(normalizedNumber), nuisanceReport.isNuisance);
         if (cursor != null) {
             try {
                 while (cursor.moveToNext()) {
diff --git a/tests/src/com/android/server/telecom/tests/CallAudioRouteTransitionTests.java b/tests/src/com/android/server/telecom/tests/CallAudioRouteTransitionTests.java
index 26d2419..e63fe9b 100644
--- a/tests/src/com/android/server/telecom/tests/CallAudioRouteTransitionTests.java
+++ b/tests/src/com/android/server/telecom/tests/CallAudioRouteTransitionTests.java
@@ -507,7 +507,7 @@
                 CallAudioState.ROUTE_BLUETOOTH, // initialRoute
                 CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // availableRoutes
                 OPTIONAL, // speakerInteraction
-                OFF, // bluetoothInteraction
+                NONE, // bluetoothInteraction
                 SPECIAL_DISCONNECT_BT_ACTION, // action
                 CallAudioState.ROUTE_EARPIECE, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE, // expectedAvailableRoutes
@@ -519,7 +519,7 @@
                 CallAudioState.ROUTE_BLUETOOTH, // initialRoute
                 CallAudioState.ROUTE_WIRED_HEADSET | CallAudioState.ROUTE_BLUETOOTH, // availableRou
                 OPTIONAL, // speakerInteraction
-                OFF, // bluetoothInteraction
+                NONE, // bluetoothInteraction
                 SPECIAL_DISCONNECT_BT_ACTION, // action
                 CallAudioState.ROUTE_WIRED_HEADSET, // expectedRoute
                 CallAudioState.ROUTE_WIRED_HEADSET, // expectedAvailableRoutes
@@ -711,7 +711,7 @@
                 CallAudioState.ROUTE_BLUETOOTH, // initialRoute
                 CallAudioState.ROUTE_BLUETOOTH,  // availableRoutes
                 ON, // speakerInteraction
-                OFF, // bluetoothInteraction
+                NONE, // bluetoothInteraction
                 SPECIAL_DISCONNECT_BT_ACTION, // action
                 CallAudioState.ROUTE_SPEAKER, // expectedRoute
                 CallAudioState.ROUTE_SPEAKER, // expectedAvailableRoutes
@@ -723,7 +723,7 @@
                 CallAudioState.ROUTE_BLUETOOTH, // initialRoute
                 CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // availableRoutes
                 OPTIONAL, // speakerInteraction
-                OFF, // bluetoothInteraction
+                NONE, // bluetoothInteraction
                 CallAudioRouteStateMachine.BT_ACTIVE_DEVICE_GONE, // action
                 CallAudioState.ROUTE_EARPIECE, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // expectedAvailabl