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

Commit e3862f95 authored by Joseph Pirozzo's avatar Joseph Pirozzo
Browse files

AVRCP Controller play while browsing

Update state machine to handle asynchronous controller data while
browsing.  Specifically, resolve issues where long running browser fetch
commands are in progress when a track changes or user presses the play
button.

Bug: 131087752
Test: atest AvrcpControllerStateMachineTest
Change-Id: I046b41af5d03cfe7f5f068a9f8615a15fb25e9b2
(cherry picked from commit 3949ea6c)
parent 2786a8ad
Loading
Loading
Loading
Loading
+12 −0
Original line number Original line Diff line number Diff line
@@ -533,6 +533,18 @@ class AvrcpControllerStateMachine extends StateMachine {
                    }
                    }
                    break;
                    break;


                case CONNECT:
                case DISCONNECT:
                case MSG_AVRCP_PASSTHRU:
                case MESSAGE_PROCESS_SET_ABS_VOL_CMD:
                case MESSAGE_PROCESS_REGISTER_ABS_VOL_NOTIFICATION:
                case MESSAGE_PROCESS_TRACK_CHANGED:
                case MESSAGE_PROCESS_PLAY_POS_CHANGED:
                case MESSAGE_PROCESS_PLAY_STATUS_CHANGED:
                case MESSAGE_PROCESS_VOLUME_CHANGED_NOTIFICATION:
                    // All of these messages should be handled by parent state immediately.
                    return false;

                default:
                default:
                    logD(STATE_TAG + " deferring message " + msg.what
                    logD(STATE_TAG + " deferring message " + msg.what
                                + " to connected!");
                                + " to connected!");
+34 −1
Original line number Original line Diff line number Diff line
@@ -27,6 +27,7 @@ import android.os.Looper;


import androidx.test.InstrumentationRegistry;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.MediumTest;
import androidx.test.filters.MediumTest;
import androidx.test.rule.ServiceTestRule;
import androidx.test.runner.AndroidJUnit4;
import androidx.test.runner.AndroidJUnit4;


import com.android.bluetooth.R;
import com.android.bluetooth.R;
@@ -39,6 +40,7 @@ import org.junit.After;
import org.junit.Assert;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentCaptor;
@@ -62,6 +64,8 @@ public class AvrcpControllerStateMachineTest {
    private ArgumentCaptor<Intent> mIntentArgument = ArgumentCaptor.forClass(Intent.class);
    private ArgumentCaptor<Intent> mIntentArgument = ArgumentCaptor.forClass(Intent.class);
    private byte[] mTestAddress = new byte[]{00, 01, 02, 03, 04, 05};
    private byte[] mTestAddress = new byte[]{00, 01, 02, 03, 04, 05};


    @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule();

    @Mock
    @Mock
    private AdapterService mAdapterService;
    private AdapterService mAdapterService;
    @Mock
    @Mock
@@ -83,6 +87,7 @@ public class AvrcpControllerStateMachineTest {
        // Setup mocks and test assets
        // Setup mocks and test assets
        MockitoAnnotations.initMocks(this);
        MockitoAnnotations.initMocks(this);
        TestUtils.setAdapterService(mAdapterService);
        TestUtils.setAdapterService(mAdapterService);
        TestUtils.startService(mServiceRule, AvrcpControllerService.class);


        // This line must be called to make sure relevant objects are initialized properly
        // This line must be called to make sure relevant objects are initialized properly
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        mAdapter = BluetoothAdapter.getDefaultAdapter();
@@ -102,7 +107,7 @@ public class AvrcpControllerStateMachineTest {
    }
    }


    /**
    /**
     * Test to confirm that the state machine is capable of cycling throught the 4
     * Test to confirm that the state machine is capable of cycling through the 4
     * connection states, and that upon completion, it cleans up aftwards.
     * connection states, and that upon completion, it cleans up aftwards.
     */
     */
    @Test
    @Test
@@ -350,6 +355,34 @@ public class AvrcpControllerStateMachineTest {
                eq(mTestAddress), eq(0), eq(19));
                eq(mTestAddress), eq(0), eq(19));
    }
    }


    /**
     * Test that AVRCP events such as playback commands can execute while performing browsing.
     */
    @Test
    public void testPlayWhileBrowsing() {
        setUpConnectedState();
        final String rootName = "__ROOT__";
        final String playerName = "Player 1";

        //Get the root of the device
        BrowseTree.BrowseNode results = mAvrcpStateMachine.findNode(rootName);
        Assert.assertEquals(rootName + mTestDevice.toString(), results.getID());

        //Request fetch the list of players
        BrowseTree.BrowseNode playerNodes = mAvrcpStateMachine.findNode(results.getID());
        mAvrcpStateMachine.requestContents(results);

        MediaController.TransportControls transportControls =
                BluetoothMediaBrowserService.getTransportControls();
        transportControls.play();
        verify(mAvrcpControllerService,
                timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)).sendPassThroughCommandNative(
                eq(mTestAddress), eq(AvrcpControllerService.PASS_THRU_CMD_ID_PLAY), eq(KEY_DOWN));
        verify(mAvrcpControllerService,
                timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)).sendPassThroughCommandNative(
                eq(mTestAddress), eq(AvrcpControllerService.PASS_THRU_CMD_ID_PLAY), eq(KEY_UP));
    }

    /**
    /**
     * Setup Connected State
     * Setup Connected State
     *
     *