Merge "Import translations. DO NOT MERGE ANYWHERE" into main
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index 1da72a0..ccf2ae3 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -37,7 +37,6 @@
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.SystemClock;
-import android.os.Trace;
 import android.os.UserHandle;
 import android.provider.CallLog;
 import android.provider.ContactsContract.Contacts;
@@ -3863,7 +3862,6 @@
      * @param callerInfo The new caller information to set.
      */
     private void setCallerInfo(Uri handle, CallerInfo callerInfo) {
-        Trace.beginSection("setCallerInfo");
         if (callerInfo == null) {
             Log.i(this, "CallerInfo lookup returned null, skipping update");
             return;
@@ -3887,8 +3885,6 @@
                 l.onCallerInfoChanged(this);
             }
         }
-
-        Trace.endSection();
     }
 
     public CallerInfo getCallerInfo() {
diff --git a/src/com/android/server/telecom/CallAudioModeStateMachine.java b/src/com/android/server/telecom/CallAudioModeStateMachine.java
index cd1d6a3..fb196f2 100644
--- a/src/com/android/server/telecom/CallAudioModeStateMachine.java
+++ b/src/com/android/server/telecom/CallAudioModeStateMachine.java
@@ -21,7 +21,6 @@
 import android.media.AudioManager;
 import android.os.Looper;
 import android.os.Message;
-import android.os.Trace;
 import android.telecom.Log;
 import android.telecom.Logging.Runnable;
 import android.telecom.Logging.Session;
@@ -461,40 +460,35 @@
         private boolean mHasFocus = false;
 
         private void tryStartRinging() {
-            Trace.traceBegin(Trace.TRACE_TAG_AUDIO, "CallAudioMode.tryStartRinging");
-            try {
-                if (mHasFocus && mCallAudioManager.isRingtonePlaying()) {
-                    Log.i(LOG_TAG,
-                        "RingingFocusState#tryStartRinging -- audio focus previously"
-                            + " acquired and ringtone already playing -- skipping.");
-                    return;
-                }
+            if (mHasFocus && mCallAudioManager.isRingtonePlaying()) {
+                Log.i(LOG_TAG,
+                    "RingingFocusState#tryStartRinging -- audio focus previously"
+                        + " acquired and ringtone already playing -- skipping.");
+                return;
+            }
 
-                if (mCallAudioManager.startRinging()) {
-                    if (mFeatureFlags.telecomResolveHiddenDependencies()) {
-                        mCurrentAudioFocusRequest = RING_AUDIO_FOCUS_REQUEST;
-                        Log.i(this, "tryStartRinging: AudioManager#requestAudioFocus(RING)");
-                        mAudioManager.requestAudioFocus(RING_AUDIO_FOCUS_REQUEST);
-                    } else {
-                        mAudioManager.requestAudioFocusForCall(
-                                AudioManager.STREAM_RING, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
-                    }
-                    // Do not set MODE_RINGTONE if we were previously in the CALL_SCREENING mode --
-                    // this trips up the audio system.
-                    if (mAudioManager.getMode() != AudioManager.MODE_CALL_SCREENING) {
-                        Log.i(this, "enter: AudioManager#setMode(MODE_RINGTONE)");
-                        mAudioManager.setMode(AudioManager.MODE_RINGTONE);
-                        mLocalLog.log("Mode MODE_RINGTONE");
-                    }
-                    mCallAudioManager.setCallAudioRouteFocusState(
-                        CallAudioRouteStateMachine.RINGING_FOCUS);
-                    mHasFocus = true;
+            if (mCallAudioManager.startRinging()) {
+                if (mFeatureFlags.telecomResolveHiddenDependencies()) {
+                    mCurrentAudioFocusRequest = RING_AUDIO_FOCUS_REQUEST;
+                    Log.i(this, "tryStartRinging: AudioManager#requestAudioFocus(RING)");
+                    mAudioManager.requestAudioFocus(RING_AUDIO_FOCUS_REQUEST);
                 } else {
-                    Log.i(
-                        LOG_TAG, "RINGING state, try start ringing but not acquiring audio focus");
+                    mAudioManager.requestAudioFocusForCall(
+                            AudioManager.STREAM_RING, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
                 }
-            } finally {
-                Trace.traceEnd(Trace.TRACE_TAG_AUDIO);
+                // Do not set MODE_RINGTONE if we were previously in the CALL_SCREENING mode --
+                // this trips up the audio system.
+                if (mAudioManager.getMode() != AudioManager.MODE_CALL_SCREENING) {
+                    Log.i(this, "enter: AudioManager#setMode(MODE_RINGTONE)");
+                    mAudioManager.setMode(AudioManager.MODE_RINGTONE);
+                    mLocalLog.log("Mode MODE_RINGTONE");
+                }
+                mCallAudioManager.setCallAudioRouteFocusState(
+                    CallAudioRouteStateMachine.RINGING_FOCUS);
+                mHasFocus = true;
+            } else {
+                Log.i(
+                    LOG_TAG, "RINGING state, try start ringing but not acquiring audio focus");
             }
         }
 
diff --git a/src/com/android/server/telecom/CallAudioRouteController.java b/src/com/android/server/telecom/CallAudioRouteController.java
index 9c593f4..9446746 100644
--- a/src/com/android/server/telecom/CallAudioRouteController.java
+++ b/src/com/android/server/telecom/CallAudioRouteController.java
@@ -533,14 +533,6 @@
                 mIsScoAudioConnected);
         mIsActive = active;
         mPendingAudioRoute.evaluatePendingState();
-        postTimeoutMessage();
-    }
-
-    private void postTimeoutMessage() {
-        // reset timeout handler
-        mHandler.removeMessages(PENDING_ROUTE_TIMEOUT);
-        mHandler.postDelayed(() -> mHandler.sendMessage(
-                Message.obtain(mHandler, PENDING_ROUTE_TIMEOUT)), TIMEOUT_LIMIT);
     }
 
     private void handleWiredHeadsetConnected() {
@@ -657,9 +649,6 @@
                 mPendingAudioRoute.onMessageReceived(new Pair<>(BT_AUDIO_CONNECTED,
                         bluetoothDevice.getAddress()), null);
             }
-        } else {
-            // ignore, not triggered by telecom
-            Log.i(this, "handleBtAudioActive: ignoring handling bt audio active.");
         }
     }
 
@@ -679,9 +668,6 @@
                 mPendingAudioRoute.onMessageReceived(new Pair<>(BT_AUDIO_DISCONNECTED,
                         bluetoothDevice.getAddress()), null);
             }
-        } else {
-            // ignore, not triggered by telecom
-            Log.i(this, "handleBtAudioInactive: ignoring handling bt audio inactive.");
         }
     }
 
@@ -1227,7 +1213,8 @@
 
     public AudioRoute getBaseRoute(boolean includeBluetooth, String btAddressToExclude) {
         AudioRoute destRoute = getPreferredAudioRouteFromStrategy();
-        if (destRoute == null || (destRoute.getBluetoothAddress() != null && !includeBluetooth)) {
+        if (destRoute == null || (destRoute.getBluetoothAddress() != null && (!includeBluetooth
+                || destRoute.getBluetoothAddress().equals(btAddressToExclude)))) {
             destRoute = getPreferredAudioRouteFromDefault(includeBluetooth, btAddressToExclude);
         }
         if (destRoute != null && !getCallSupportedRoutes().contains(destRoute)) {
diff --git a/src/com/android/server/telecom/CallIntentProcessor.java b/src/com/android/server/telecom/CallIntentProcessor.java
index 8e1f754..c77b9ff 100644
--- a/src/com/android/server/telecom/CallIntentProcessor.java
+++ b/src/com/android/server/telecom/CallIntentProcessor.java
@@ -14,7 +14,6 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Looper;
-import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.telecom.DefaultDialerManager;
@@ -95,14 +94,12 @@
         final boolean isUnknownCall = intent.getBooleanExtra(KEY_IS_UNKNOWN_CALL, false);
         Log.i(this, "onReceive - isUnknownCall: %s", isUnknownCall);
 
-        Trace.beginSection("processNewCallCallIntent");
         if (isUnknownCall) {
             processUnknownCallIntent(mCallsManager, intent);
         } else {
             processOutgoingCallIntent(mContext, mCallsManager, intent, callingPackage,
                     mDefaultDialerCache, mFeatureFlags);
         }
-        Trace.endSection();
     }
 
 
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 369bc8a..0c4d95d 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -75,7 +75,6 @@
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.SystemVibrator;
-import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.BlockedNumberContract;
@@ -4629,7 +4628,6 @@
             Log.i(this, "addCall(%s) is already added");
             return;
         }
-        Trace.beginSection("addCall");
         Log.i(this, "addCall(%s)", call);
         call.addListener(this);
         mCalls.add(call);
@@ -4646,20 +4644,12 @@
         updateExternalCallCanPullSupport();
         // onCallAdded for calls which immediately take the foreground (like the first call).
         for (CallsManagerListener listener : mListeners) {
-            if (LogUtils.SYSTRACE_DEBUG) {
-                Trace.beginSection(listener.getClass().toString() + " addCall");
-            }
             listener.onCallAdded(call);
-            if (LogUtils.SYSTRACE_DEBUG) {
-                Trace.endSection();
-            }
         }
-        Trace.endSection();
     }
 
     @VisibleForTesting
     public void removeCall(Call call) {
-        Trace.beginSection("removeCall");
         Log.v(this, "removeCall(%s)", call);
 
         if (call.isTransactionalCall() && call.getTransactionServiceWrapper() != null) {
@@ -4686,16 +4676,9 @@
             updateCanAddCall();
             updateHasActiveRttCall();
             for (CallsManagerListener listener : mListeners) {
-                if (LogUtils.SYSTRACE_DEBUG) {
-                    Trace.beginSection(listener.getClass().toString() + " onCallRemoved");
-                }
                 listener.onCallRemoved(call);
-                if (LogUtils.SYSTRACE_DEBUG) {
-                    Trace.endSection();
-                }
             }
         }
-        Trace.endSection();
     }
 
     private void updateHasActiveRttCall() {
@@ -4758,13 +4741,8 @@
                 call.getAnalytics().setMissedReason(call.getMissedReason());
 
                 maybeShowErrorDialogOnDisconnect(call);
-
-                Trace.beginSection("onCallStateChanged");
-
                 maybeHandleHandover(call, newState);
                 notifyCallStateChanged(call, oldState, newState);
-
-                Trace.endSection();
             } else {
                 Log.i(this, "failed in setting the state to new state");
             }
@@ -4777,14 +4755,7 @@
             updateCanAddCall();
             updateHasActiveRttCall();
             for (CallsManagerListener listener : mListeners) {
-                if (LogUtils.SYSTRACE_DEBUG) {
-                    Trace.beginSection(listener.getClass().toString() +
-                            " onCallStateChanged");
-                }
                 listener.onCallStateChanged(call, oldState, newState);
-                if (LogUtils.SYSTRACE_DEBUG) {
-                    Trace.endSection();
-                }
             }
         }
     }
@@ -4909,13 +4880,7 @@
         if (newCanAddCall != mCanAddCall) {
             mCanAddCall = newCanAddCall;
             for (CallsManagerListener listener : mListeners) {
-                if (LogUtils.SYSTRACE_DEBUG) {
-                    Trace.beginSection(listener.getClass().toString() + " updateCanAddCall");
-                }
                 listener.onCanAddCallChanged(mCanAddCall);
-                if (LogUtils.SYSTRACE_DEBUG) {
-                    Trace.endSection();
-                }
             }
         }
     }
diff --git a/src/com/android/server/telecom/InCallController.java b/src/com/android/server/telecom/InCallController.java
index 6164638..0f62f87 100644
--- a/src/com/android/server/telecom/InCallController.java
+++ b/src/com/android/server/telecom/InCallController.java
@@ -45,7 +45,6 @@
 import android.os.Looper;
 import android.os.PackageTagsList;
 import android.os.RemoteException;
-import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.telecom.CallAudioState;
@@ -2573,7 +2572,6 @@
             Log.e(this, e, "Failed to set the in-call adapter.");
             mAnomalyReporter.reportAnomaly(SET_IN_CALL_ADAPTER_ERROR_UUID,
                     SET_IN_CALL_ADAPTER_ERROR_MSG);
-            Trace.endSection();
             return false;
         }
 
diff --git a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
index c24ac97..fce3f1a 100644
--- a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
+++ b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
@@ -25,7 +25,6 @@
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
-import android.os.Trace;
 import android.os.UserHandle;
 import android.telecom.GatewayInfo;
 import android.telecom.Log;
@@ -126,7 +125,6 @@
         public void onReceive(Context context, Intent intent) {
             try {
                 Log.startSession("NOCBIR.oR");
-                Trace.beginSection("onReceiveNewOutgoingCallBroadcast");
                 synchronized (mLock) {
                     Log.v(this, "onReceive: %s", intent);
 
@@ -194,7 +192,6 @@
                                     VideoProfile.STATE_AUDIO_ONLY));
                 }
             } finally {
-                Trace.endSection();
                 Log.endSession();
             }
         }
diff --git a/src/com/android/server/telecom/bluetooth/BluetoothStateReceiver.java b/src/com/android/server/telecom/bluetooth/BluetoothStateReceiver.java
index b4c3d8d..cd52889 100644
--- a/src/com/android/server/telecom/bluetooth/BluetoothStateReceiver.java
+++ b/src/com/android/server/telecom/bluetooth/BluetoothStateReceiver.java
@@ -23,6 +23,8 @@
 import static com.android.server.telecom.CallAudioRouteAdapter.BT_DEVICE_ADDED;
 import static com.android.server.telecom.CallAudioRouteAdapter.BT_DEVICE_REMOVED;
 import static com.android.server.telecom.CallAudioRouteAdapter.PENDING_ROUTE_FAILED;
+import static com.android.server.telecom.CallAudioRouteAdapter.SWITCH_BASELINE_ROUTE;
+import static com.android.server.telecom.CallAudioRouteController.INCLUDE_BLUETOOTH_IN_BASELINE;
 import static com.android.server.telecom.bluetooth.BluetoothRouteManager.BT_AUDIO_IS_ON;
 import static com.android.server.telecom.bluetooth.BluetoothRouteManager.BT_AUDIO_LOST;
 
@@ -153,8 +155,19 @@
                     CallAudioRouteController audioRouteController =
                             (CallAudioRouteController) mCallAudioRouteAdapter;
                     audioRouteController.setIsScoAudioConnected(false);
-                    mCallAudioRouteAdapter.sendMessageWithSessionInfo(BT_AUDIO_DISCONNECTED, 0,
-                            device);
+                    if (audioRouteController.isPending()) {
+                        mCallAudioRouteAdapter.sendMessageWithSessionInfo(BT_AUDIO_DISCONNECTED, 0,
+                                device);
+                    } else {
+                        // Handle case where BT stack signals SCO disconnected but Telecom isn't
+                        // processing any pending routes. This explicitly addresses cf instances
+                        // where a remote device disconnects SCO. Telecom should ensure that audio
+                        // is properly routed in the UI.
+                        audioRouteController.getPendingAudioRoute()
+                                .setCommunicationDeviceType(AudioRoute.TYPE_INVALID);
+                        mCallAudioRouteAdapter.sendMessageWithSessionInfo(SWITCH_BASELINE_ROUTE,
+                                INCLUDE_BLUETOOTH_IN_BASELINE, device.getAddress());
+                    }
                 }  else {
                     mBluetoothRouteManager.sendMessage(BT_AUDIO_LOST, args);
                 }