Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5cfe9a46 authored by Pranav Madapurmath's avatar Pranav Madapurmath
Browse files

Add flag for communication device refactor.

Add missing flag dependency for the call audio communication device
refactor work that was introduced as part of U. This CL also ensures
that the device set for communication is cleared when the audio mode is
set back to MODE_NORMAL (after call ends) and that the audio lost signal
is sent after the device has been cleared for communication. The latter
addresses issues with switching from a bluetooth LE audio device to
speaker to ensure that the device isn't considered an active device
still when switching audio routes.

Bug: 308968392
Test: atest TelecomUnitTests
Test: Manual to ensure that device set for communication is cleared
after a call ends.

Change-Id: I62a0d65c53b67a307b23d1015b994796e955a6aa
parent e41337d7
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -27,3 +27,10 @@ flag {
  description: "Fix audio route transition issue on call disconnection when bt audio connected."
  bug: "306113816"
}

flag {
  name: "call_audio_communication_device_refactor"
  namespace: "telecom"
  description: "Refactor call audio set/clear communication device and include unsupported routes."
  bug: "308968392"
}
 No newline at end of file
+10 −6
Original line number Diff line number Diff line
@@ -63,6 +63,10 @@ public class CallAudioCommunicationDeviceTracker {
        return mAudioDeviceType == audioDeviceType;
    }

    public int getCurrentLocallyRequestedCommunicationDevice() {
       return mAudioDeviceType;
    }

    @VisibleForTesting
    public void setTestCommunicationDevice(int audioDeviceType) {
        mAudioDeviceType = audioDeviceType;
@@ -177,12 +181,6 @@ public class CallAudioCommunicationDeviceTracker {
            return;
        }

        if (isBtDevice && mBtAudioDevice != null) {
            // Signal that BT audio was lost for device.
            mBluetoothRouteManager.onAudioLost(mBtAudioDevice);
            mBtAudioDevice = null;
        }

        if (mAudioManager == null) {
            Log.i(this, "clearCommunicationDevice: mAudioManager is null");
            return;
@@ -191,6 +189,12 @@ public class CallAudioCommunicationDeviceTracker {
        // Clear device and reset locally saved device type.
        mAudioManager.clearCommunicationDevice();
        mAudioDeviceType = sAUDIO_DEVICE_TYPE_INVALID;

        if (isBtDevice && mBtAudioDevice != null) {
            // Signal that BT audio was lost for device.
            mBluetoothRouteManager.onAudioLost(mBtAudioDevice);
            mBtAudioDevice = null;
        }
    }

    private boolean isUsbHeadsetType(int audioDeviceType, int sourceType) {
+16 −4
Original line number Diff line number Diff line
@@ -41,8 +41,10 @@ public class CallAudioModeStateMachine extends StateMachine {
    private LocalLog mLocalLog = new LocalLog(20);
    public static class Factory {
        public CallAudioModeStateMachine create(SystemStateHelper systemStateHelper,
                                                AudioManager am, FeatureFlags featureFlags) {
            return new CallAudioModeStateMachine(systemStateHelper, am, featureFlags);
                AudioManager am, FeatureFlags featureFlags,
                CallAudioCommunicationDeviceTracker callAudioCommunicationDeviceTracker) {
            return new CallAudioModeStateMachine(systemStateHelper, am,
                    featureFlags, callAudioCommunicationDeviceTracker);
        }
    }

@@ -277,6 +279,11 @@ public class CallAudioModeStateMachine extends StateMachine {
            Log.i(LOG_TAG, "Audio focus entering UNFOCUSED state");
            mLocalLog.log("Enter UNFOCUSED");
            if (mIsInitialized) {
                // Clear any communication device that was requested previously.
                if (mFeatureFlags.callAudioCommunicationDeviceRefactor()) {
                    mCommunicationDeviceTracker.clearCommunicationDevice(mCommunicationDeviceTracker
                            .getCurrentLocallyRequestedCommunicationDevice());
                }
                if (mFeatureFlags.setAudioModeBeforeAbandonFocus()) {
                    mAudioManager.setMode(AudioManager.MODE_NORMAL);
                    mCallAudioManager.setCallAudioRouteFocusState(
@@ -878,17 +885,20 @@ public class CallAudioModeStateMachine extends StateMachine {
    private final SystemStateHelper mSystemStateHelper;
    private CallAudioManager mCallAudioManager;
    private FeatureFlags mFeatureFlags;
    private CallAudioCommunicationDeviceTracker mCommunicationDeviceTracker;

    private int mMostRecentMode;
    private boolean mIsInitialized = false;

    public CallAudioModeStateMachine(SystemStateHelper systemStateHelper,
            AudioManager audioManager, FeatureFlags featureFlags) {
            AudioManager audioManager, FeatureFlags featureFlags,
            CallAudioCommunicationDeviceTracker callAudioCommunicationDeviceTracker) {
        super(CallAudioModeStateMachine.class.getSimpleName());
        mAudioManager = audioManager;
        mSystemStateHelper = systemStateHelper;
        mMostRecentMode = AudioManager.MODE_NORMAL;
        mFeatureFlags = featureFlags;
        mCommunicationDeviceTracker = callAudioCommunicationDeviceTracker;

        createStates();
    }
@@ -897,12 +907,14 @@ public class CallAudioModeStateMachine extends StateMachine {
     * Used for testing
     */
    public CallAudioModeStateMachine(SystemStateHelper systemStateHelper,
            AudioManager audioManager, Looper looper, FeatureFlags featureFlags) {
            AudioManager audioManager, Looper looper, FeatureFlags featureFlags,
            CallAudioCommunicationDeviceTracker communicationDeviceTracker) {
        super(CallAudioModeStateMachine.class.getSimpleName(), looper);
        mAudioManager = audioManager;
        mSystemStateHelper = systemStateHelper;
        mMostRecentMode = AudioManager.MODE_NORMAL;
        mFeatureFlags = featureFlags;
        mCommunicationDeviceTracker = communicationDeviceTracker;

        createStates();
    }
+73 −23
Original line number Diff line number Diff line
@@ -377,8 +377,10 @@ public class CallAudioRouteStateMachine extends StateMachine {
        public void enter() {
            super.enter();
            setSpeakerphoneOn(false);
            if (mFeatureFlags.callAudioCommunicationDeviceRefactor()) {
                mCommunicationDeviceTracker.setCommunicationDevice(
                        AudioDeviceInfo.TYPE_BUILTIN_EARPIECE, null);
            }
            CallAudioState newState = new CallAudioState(mIsMuted, ROUTE_EARPIECE,
                    mAvailableRoutes, null,
                    mBluetoothRouteManager.getConnectedDevices());
@@ -409,8 +411,10 @@ public class CallAudioRouteStateMachine extends StateMachine {
                case SWITCH_BLUETOOTH:
                case USER_SWITCH_BLUETOOTH:
                    if ((mAvailableRoutes & ROUTE_BLUETOOTH) != 0) {
                        if (mFeatureFlags.callAudioCommunicationDeviceRefactor()) {
                            mCommunicationDeviceTracker.clearCommunicationDevice(
                                    AudioDeviceInfo.TYPE_BUILTIN_EARPIECE);
                        }
                        if (mAudioFocusType == ACTIVE_FOCUS
                                || mBluetoothRouteManager.isInbandRingingEnabled()) {
                            String address = (msg.obj instanceof SomeArgs) ?
@@ -427,8 +431,10 @@ public class CallAudioRouteStateMachine extends StateMachine {
                case SWITCH_HEADSET:
                case USER_SWITCH_HEADSET:
                    if ((mAvailableRoutes & ROUTE_WIRED_HEADSET) != 0) {
                        if (mFeatureFlags.callAudioCommunicationDeviceRefactor()) {
                            mCommunicationDeviceTracker.clearCommunicationDevice(
                                    AudioDeviceInfo.TYPE_BUILTIN_EARPIECE);
                        }
                        transitionTo(mActiveHeadsetRoute);
                    } else {
                        Log.w(this, "Ignoring switch to headset command. Not available.");
@@ -438,8 +444,10 @@ public class CallAudioRouteStateMachine extends StateMachine {
                    // fall through; we want to switch to speaker mode when docked and in a call.
                case SWITCH_SPEAKER:
                case USER_SWITCH_SPEAKER:
                    if (mFeatureFlags.callAudioCommunicationDeviceRefactor()) {
                        mCommunicationDeviceTracker.clearCommunicationDevice(
                                AudioDeviceInfo.TYPE_BUILTIN_EARPIECE);
                    }
                    setSpeakerphoneOn(true);
                    // fall through
                case SPEAKER_ON:
@@ -593,8 +601,10 @@ public class CallAudioRouteStateMachine extends StateMachine {
        public void enter() {
            super.enter();
            setSpeakerphoneOn(false);
            if (mFeatureFlags.callAudioCommunicationDeviceRefactor()) {
                mCommunicationDeviceTracker.setCommunicationDevice(
                        AudioDeviceInfo.TYPE_WIRED_HEADSET, null);
            }
            CallAudioState newState = new CallAudioState(mIsMuted, ROUTE_WIRED_HEADSET,
                    mAvailableRoutes, null, mBluetoothRouteManager.getConnectedDevices());
            setSystemAudioState(newState, true);
@@ -616,8 +626,10 @@ public class CallAudioRouteStateMachine extends StateMachine {
                case SWITCH_EARPIECE:
                case USER_SWITCH_EARPIECE:
                    if ((mAvailableRoutes & ROUTE_EARPIECE) != 0) {
                        if (mFeatureFlags.callAudioCommunicationDeviceRefactor()) {
                            mCommunicationDeviceTracker.clearCommunicationDevice(
                                    AudioDeviceInfo.TYPE_WIRED_HEADSET);
                        }
                        transitionTo(mActiveEarpieceRoute);
                    } else {
                        Log.w(this, "Ignoring switch to earpiece command. Not available.");
@@ -633,8 +645,10 @@ public class CallAudioRouteStateMachine extends StateMachine {
                                || mBluetoothRouteManager.isInbandRingingEnabled()) {
                            String address = (msg.obj instanceof SomeArgs) ?
                                    (String) ((SomeArgs) msg.obj).arg2 : null;
                            if (mFeatureFlags.callAudioCommunicationDeviceRefactor()) {
                                mCommunicationDeviceTracker.clearCommunicationDevice(
                                        AudioDeviceInfo.TYPE_WIRED_HEADSET);
                            }
                            // Omit transition to ActiveBluetoothRoute until actual connection.
                            setBluetoothOn(address);
                        } else {
@@ -651,8 +665,10 @@ public class CallAudioRouteStateMachine extends StateMachine {
                    return HANDLED;
                case SWITCH_SPEAKER:
                case USER_SWITCH_SPEAKER:
                    if (mFeatureFlags.callAudioCommunicationDeviceRefactor()) {
                        mCommunicationDeviceTracker.clearCommunicationDevice(
                                AudioDeviceInfo.TYPE_WIRED_HEADSET);
                    }
                    setSpeakerphoneOn(true);
                    // fall through
                case SPEAKER_ON:
@@ -820,7 +836,9 @@ public class CallAudioRouteStateMachine extends StateMachine {
            // the BT connection fails to be set. Previously, the logic was to setBluetoothOn in
            // ACTIVE_FOCUS but the route would still remain in a quiescent route, so instead we
            // should be transitioning directly into the active route.
            if (mFeatureFlags.callAudioCommunicationDeviceRefactor()) {
                setBluetoothOn(null);
            }
            CallAudioState newState = new CallAudioState(mIsMuted, ROUTE_BLUETOOTH,
                    mAvailableRoutes, mBluetoothRouteManager.getBluetoothAudioConnectedDevice(),
                    mBluetoothRouteManager.getConnectedDevices());
@@ -1100,7 +1118,11 @@ public class CallAudioRouteStateMachine extends StateMachine {
                    if (msg.arg1 == ACTIVE_FOCUS) {
                        // It is possible that the connection to BT will fail while in-call, in
                        // which case, we want to transition into the active route.
                        if (mFeatureFlags.callAudioCommunicationDeviceRefactor()) {
                            transitionTo(mActiveBluetoothRoute);
                        } else {
                            setBluetoothOn(null);
                        }
                    } else if (msg.arg1 == RINGING_FOCUS) {
                        if (mBluetoothRouteManager.isInbandRingingEnabled()) {
                            setBluetoothOn(null);
@@ -1802,6 +1824,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
        // These APIs are all via two-way binder calls so can potentially block Telecom.  Since none
        // of this has to happen in the Telecom lock we'll offload it to the async executor.
        boolean speakerOn = false;
        if (mFeatureFlags.callAudioCommunicationDeviceRefactor()) {
            if (on) {
                speakerOn = mCommunicationDeviceTracker.setCommunicationDevice(
                        AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, null);
@@ -1809,6 +1832,9 @@ public class CallAudioRouteStateMachine extends StateMachine {
                mCommunicationDeviceTracker.clearCommunicationDevice(
                        AudioDeviceInfo.TYPE_BUILTIN_SPEAKER);
            }
        } else {
            processLegacySpeakerCommunicationDevice(on);
        }
        mStatusBarNotifier.notifySpeakerphone(hasAnyCalls && speakerOn);
    }

@@ -2057,6 +2083,30 @@ public class CallAudioRouteStateMachine extends StateMachine {
        return containsWatchDevice && !containsNonWatchDevice && !isActiveDeviceWatch;
    }

    private boolean processLegacySpeakerCommunicationDevice(boolean on) {
        AudioDeviceInfo speakerDevice = null;
        for (AudioDeviceInfo info : mAudioManager.getAvailableCommunicationDevices()) {
            if (info.getType() == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) {
                speakerDevice = info;
                break;
            }
        }
        boolean speakerOn = false;
        if (speakerDevice != null && on) {
            boolean result = mAudioManager.setCommunicationDevice(speakerDevice);
            if (result) {
                speakerOn = true;
            }
        } else {
            AudioDeviceInfo curDevice = mAudioManager.getCommunicationDevice();
            if (curDevice != null
                    && curDevice.getType() == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) {
                mAudioManager.clearCommunicationDevice();
            }
        }
        return speakerOn;
    }

    private int calculateBaselineRouteMessage(boolean isExplicitUserRequest,
            boolean includeBluetooth) {
        boolean isSkipEarpiece = false;
+2 −1
Original line number Diff line number Diff line
@@ -656,7 +656,8 @@ public class CallsManager extends Call.ListenerBase
                mTimeoutsAdapter, mLock);
        mCallAudioManager = new CallAudioManager(callAudioRouteStateMachine,
                this, callAudioModeStateMachineFactory.create(systemStateHelper,
                (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE), featureFlags),
                (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE),
                featureFlags, communicationDeviceTracker),
                playerFactory, mRinger, new RingbackPlayer(playerFactory),
                bluetoothStateReceiver, mDtmfLocalTonePlayer, featureFlags);

Loading