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

Commit e00f04e5 authored by Pavlin Radoslavov's avatar Pavlin Radoslavov
Browse files

Add missing Avrcp.doQuit() call during A2dpService stop()

During graceful shutdown of A2DP, proper cleanup of AVRCP
requires calling both Avrcp.doQuit() and Avrcp.cleanup() .

Also, reorder the AVRCP-related operations inside A2dpService.start()
and A2dpService.stop():
 - Avrcp.make() before preparing the A2DP state machines
 - Avrcp.doQuit() and Avrcp.cleanup() after shutting down the A2DP state
   machines.
This reordering is needed to avoid a race condition during
A2dpService graceful shutdown:
  A2dpStateMachine -> A2dpService.setAvrcpAudioState() ->
     mAvrcp.setA2dpAudioState()
while right before the last call mAvrcp was assigned to null
inside stop().

Bug: 73547689
Test: Manual (enable/disable Bluetooth)
      Unit tests pass
Change-Id: I8b30a0ff840cf73e8e9cce06b52659b2a17cac5b
parent 02bcdbff
Loading
Loading
Loading
Loading
+12 −11
Original line number Diff line number Diff line
@@ -113,18 +113,18 @@ public class A2dpService extends ProfileService {
        mMaxConnectedAudioDevices = mAdapterService.getMaxConnectedAudioDevices();
        Log.i(TAG, "Max connected audio devices set to " + mMaxConnectedAudioDevices);

        // Step 3: Start handler thread for state machines
        // Step 3: Setup AVRCP
        mAvrcp = Avrcp.make(this);

        // Step 4: Start handler thread for state machines
        mStateMachines.clear();
        mStateMachinesThread = new HandlerThread("A2dpService.StateMachines");
        mStateMachinesThread.start();

        // Step 4: Setup codec config and clear active device
        // Step 5: Setup codec config and clear active device
        mA2dpCodecConfig = new A2dpCodecConfig(this, mA2dpNativeInterface);
        mActiveDevice = null;

        // Step 5: Setup AVRCP
        mAvrcp = Avrcp.make(this);

        // Step 6: Initialize native interface
        mA2dpNativeInterface.init(mA2dpCodecConfig.codecConfigPriorities());

@@ -165,15 +165,11 @@ public class A2dpService extends ProfileService {
        mA2dpNativeInterface.cleanup();
        mA2dpNativeInterface = null;

        // Step 5: Cleanup AVRCP
        mAvrcp.cleanup();
        mAvrcp = null;

        // Step 4: Clear codec config and active device
        // Step 5: Clear codec config and active device
        mA2dpCodecConfig = null;
        mActiveDevice = null;

        // Step 3: Destroy state machines and stop handler thread
        // Step 4: Destroy state machines and stop handler thread
        synchronized (mStateMachines) {
            for (A2dpStateMachine sm : mStateMachines.values()) {
                sm.doQuit();
@@ -184,6 +180,11 @@ public class A2dpService extends ProfileService {
        mStateMachinesThread.quitSafely();
        mStateMachinesThread = null;

        // Step 3: Cleanup AVRCP
        mAvrcp.doQuit();
        mAvrcp.cleanup();
        mAvrcp = null;

        // Step 2: Reset maximum number of connected audio devices
        mMaxConnectedAudioDevices = 1;