Loading flags/telecom_incallservice_flags.aconfig +8 −1 Original line number Diff line number Diff line Loading @@ -13,3 +13,10 @@ flag { description: "Ensure that users are able to return to call from keyguard UI for ECC" bug: "306582821" } flag { name: "separately_bind_to_bt_incall_service" namespace: "telecom" description: "Binding/Unbinding to BluetoothInCallServices in proper time to improve call audio" bug: "306395598" } res/values/config.xml +3 −0 Original line number Diff line number Diff line Loading @@ -79,4 +79,7 @@ <!-- When true, the options in the call blocking settings to block unavailable and unknown callers are combined into a single toggle. --> <bool name="combine_options_to_block_unavailable_and_unknown_callers">true</bool> <!-- System bluetooth stack package name --> <string name="system_bluetooth_stack">com.android.bluetooth</string> </resources> src/com/android/server/telecom/Call.java +32 −3 Original line number Diff line number Diff line Loading @@ -27,13 +27,11 @@ import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.OutcomeReceiver; import android.os.ParcelFileDescriptor; import android.os.Parcelable; import android.os.RemoteException; import android.os.SystemClock; import android.os.Trace; Loading Loading @@ -73,7 +71,6 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telecom.IVideoProvider; import com.android.internal.util.Preconditions; import com.android.server.telecom.flags.FeatureFlags; import com.android.server.telecom.flags.Flags; import com.android.server.telecom.stats.CallFailureCause; import com.android.server.telecom.stats.CallStateChangedAtomWriter; import com.android.server.telecom.ui.ToastFactory; Loading @@ -95,6 +92,7 @@ import java.util.Objects; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; Loading Loading @@ -796,6 +794,13 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable, */ private CompletableFuture<Boolean> mDisconnectFuture; /** * {@link CompletableFuture} used to delay audio routing change for a ringing call until the * corresponding bluetooth {@link android.telecom.InCallService} is successfully bound or timed * out. */ private CompletableFuture<Boolean> mBtIcsFuture; private FeatureFlags mFlags; /** Loading Loading @@ -4692,6 +4697,30 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable, } } /** * Set the bluetooth {@link android.telecom.InCallService} binding completion or timeout future * which is used to delay the audio routing change after the bluetooth stack get notified about * the ringing calls. * @param btIcsFuture the {@link CompletableFuture} */ public void setBtIcsFuture(CompletableFuture<Boolean> btIcsFuture) { mBtIcsFuture = btIcsFuture; } /** * Wait for bluetooth {@link android.telecom.InCallService} binding completion or timeout. Used * for audio routing operations for a ringing call. */ public void waitForBtIcs() { if (mBtIcsFuture != null) { try { mBtIcsFuture.get(); } catch (InterruptedException | ExecutionException e) { // ignore } } } /** * @return {@code true} if the connection has been created by the underlying * {@link ConnectionService}, {@code false} otherwise. Loading src/com/android/server/telecom/CallAudioManager.java +4 −0 Original line number Diff line number Diff line Loading @@ -750,6 +750,10 @@ public class CallAudioManager extends CallsManagerListenerBase { private void onCallEnteringRinging() { if (mRingingCalls.size() == 1) { // Wait until the BT ICS binding completed to request further audio route change for (Call ringingCall: mRingingCalls) { ringingCall.waitForBtIcs(); } mCallAudioModeStateMachine.sendMessageWithArgs( CallAudioModeStateMachine.NEW_RINGING_CALL, makeArgsForModeStateMachine()); Loading src/com/android/server/telecom/CallsManager.java +12 −4 Original line number Diff line number Diff line Loading @@ -164,6 +164,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; Loading Loading @@ -962,8 +963,10 @@ public class CallsManager extends Call.ListenerBase if (incomingCall.getState() != CallState.DISCONNECTED && incomingCall.getState() != CallState.DISCONNECTING) { if (!mFeatureFlags.separatelyBindToBtIncallService()) { setCallState(incomingCall, CallState.RINGING, result.shouldAllowCall ? "successful incoming call" : "blocking call"); } } else { Log.i(this, "onCallFilteringCompleted: call already disconnected."); return; Loading Loading @@ -1008,6 +1011,10 @@ public class CallsManager extends Call.ListenerBase } if (result.shouldAllowCall) { if (mFeatureFlags.separatelyBindToBtIncallService()) { incomingCall.setBtIcsFuture(mInCallController.bindToBTService(incomingCall)); setCallState(incomingCall, CallState.RINGING, "successful incoming call"); } incomingCall.setPostCallPackageName( getRoleManagerAdapter().getDefaultCallScreeningApp( incomingCall.getAssociatedUser() Loading @@ -1022,7 +1029,6 @@ public class CallsManager extends Call.ListenerBase "Exceeds maximum number of ringing calls."); incomingCall.setMissedReason(AUTO_MISSED_MAXIMUM_RINGING); autoMissCallAndLog(incomingCall, result); return; } } else if (hasMaximumManagedDialingCalls(incomingCall)) { if (shouldSilenceInsteadOfReject(incomingCall)) { Loading @@ -1032,7 +1038,6 @@ public class CallsManager extends Call.ListenerBase "dialing calls."); incomingCall.setMissedReason(AUTO_MISSED_MAXIMUM_DIALING); autoMissCallAndLog(incomingCall, result); return; } } else if (result.shouldScreenViaAudio) { Log.i(this, "onCallFilteringCompleted: starting background audio processing"); Loading @@ -1051,6 +1056,9 @@ public class CallsManager extends Call.ListenerBase } else { if (result.shouldReject) { Log.i(this, "onCallFilteringCompleted: blocked call, rejecting."); if (mFeatureFlags.separatelyBindToBtIncallService()) { setCallState(incomingCall, CallState.RINGING, "blocking call"); } incomingCall.reject(false, null); } if (result.shouldAddToCallLog) { Loading Loading
flags/telecom_incallservice_flags.aconfig +8 −1 Original line number Diff line number Diff line Loading @@ -13,3 +13,10 @@ flag { description: "Ensure that users are able to return to call from keyguard UI for ECC" bug: "306582821" } flag { name: "separately_bind_to_bt_incall_service" namespace: "telecom" description: "Binding/Unbinding to BluetoothInCallServices in proper time to improve call audio" bug: "306395598" }
res/values/config.xml +3 −0 Original line number Diff line number Diff line Loading @@ -79,4 +79,7 @@ <!-- When true, the options in the call blocking settings to block unavailable and unknown callers are combined into a single toggle. --> <bool name="combine_options_to_block_unavailable_and_unknown_callers">true</bool> <!-- System bluetooth stack package name --> <string name="system_bluetooth_stack">com.android.bluetooth</string> </resources>
src/com/android/server/telecom/Call.java +32 −3 Original line number Diff line number Diff line Loading @@ -27,13 +27,11 @@ import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.OutcomeReceiver; import android.os.ParcelFileDescriptor; import android.os.Parcelable; import android.os.RemoteException; import android.os.SystemClock; import android.os.Trace; Loading Loading @@ -73,7 +71,6 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telecom.IVideoProvider; import com.android.internal.util.Preconditions; import com.android.server.telecom.flags.FeatureFlags; import com.android.server.telecom.flags.Flags; import com.android.server.telecom.stats.CallFailureCause; import com.android.server.telecom.stats.CallStateChangedAtomWriter; import com.android.server.telecom.ui.ToastFactory; Loading @@ -95,6 +92,7 @@ import java.util.Objects; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; Loading Loading @@ -796,6 +794,13 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable, */ private CompletableFuture<Boolean> mDisconnectFuture; /** * {@link CompletableFuture} used to delay audio routing change for a ringing call until the * corresponding bluetooth {@link android.telecom.InCallService} is successfully bound or timed * out. */ private CompletableFuture<Boolean> mBtIcsFuture; private FeatureFlags mFlags; /** Loading Loading @@ -4692,6 +4697,30 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable, } } /** * Set the bluetooth {@link android.telecom.InCallService} binding completion or timeout future * which is used to delay the audio routing change after the bluetooth stack get notified about * the ringing calls. * @param btIcsFuture the {@link CompletableFuture} */ public void setBtIcsFuture(CompletableFuture<Boolean> btIcsFuture) { mBtIcsFuture = btIcsFuture; } /** * Wait for bluetooth {@link android.telecom.InCallService} binding completion or timeout. Used * for audio routing operations for a ringing call. */ public void waitForBtIcs() { if (mBtIcsFuture != null) { try { mBtIcsFuture.get(); } catch (InterruptedException | ExecutionException e) { // ignore } } } /** * @return {@code true} if the connection has been created by the underlying * {@link ConnectionService}, {@code false} otherwise. Loading
src/com/android/server/telecom/CallAudioManager.java +4 −0 Original line number Diff line number Diff line Loading @@ -750,6 +750,10 @@ public class CallAudioManager extends CallsManagerListenerBase { private void onCallEnteringRinging() { if (mRingingCalls.size() == 1) { // Wait until the BT ICS binding completed to request further audio route change for (Call ringingCall: mRingingCalls) { ringingCall.waitForBtIcs(); } mCallAudioModeStateMachine.sendMessageWithArgs( CallAudioModeStateMachine.NEW_RINGING_CALL, makeArgsForModeStateMachine()); Loading
src/com/android/server/telecom/CallsManager.java +12 −4 Original line number Diff line number Diff line Loading @@ -164,6 +164,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; Loading Loading @@ -962,8 +963,10 @@ public class CallsManager extends Call.ListenerBase if (incomingCall.getState() != CallState.DISCONNECTED && incomingCall.getState() != CallState.DISCONNECTING) { if (!mFeatureFlags.separatelyBindToBtIncallService()) { setCallState(incomingCall, CallState.RINGING, result.shouldAllowCall ? "successful incoming call" : "blocking call"); } } else { Log.i(this, "onCallFilteringCompleted: call already disconnected."); return; Loading Loading @@ -1008,6 +1011,10 @@ public class CallsManager extends Call.ListenerBase } if (result.shouldAllowCall) { if (mFeatureFlags.separatelyBindToBtIncallService()) { incomingCall.setBtIcsFuture(mInCallController.bindToBTService(incomingCall)); setCallState(incomingCall, CallState.RINGING, "successful incoming call"); } incomingCall.setPostCallPackageName( getRoleManagerAdapter().getDefaultCallScreeningApp( incomingCall.getAssociatedUser() Loading @@ -1022,7 +1029,6 @@ public class CallsManager extends Call.ListenerBase "Exceeds maximum number of ringing calls."); incomingCall.setMissedReason(AUTO_MISSED_MAXIMUM_RINGING); autoMissCallAndLog(incomingCall, result); return; } } else if (hasMaximumManagedDialingCalls(incomingCall)) { if (shouldSilenceInsteadOfReject(incomingCall)) { Loading @@ -1032,7 +1038,6 @@ public class CallsManager extends Call.ListenerBase "dialing calls."); incomingCall.setMissedReason(AUTO_MISSED_MAXIMUM_DIALING); autoMissCallAndLog(incomingCall, result); return; } } else if (result.shouldScreenViaAudio) { Log.i(this, "onCallFilteringCompleted: starting background audio processing"); Loading @@ -1051,6 +1056,9 @@ public class CallsManager extends Call.ListenerBase } else { if (result.shouldReject) { Log.i(this, "onCallFilteringCompleted: blocked call, rejecting."); if (mFeatureFlags.separatelyBindToBtIncallService()) { setCallState(incomingCall, CallState.RINGING, "blocking call"); } incomingCall.reject(false, null); } if (result.shouldAddToCallLog) { Loading