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

Commit 6301d363 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 6462261 from b640370b to mainline-release

Change-Id: Iffdff2629d483e8c1138a8c6e930a1409786c10b
parents d34eb0ae b640370b
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -460,11 +460,25 @@ class AvrcpControllerStateMachine extends StateMachine {
                case MESSAGE_PROCESS_ADDRESSED_PLAYER_CHANGED:
                    mAddressedPlayerId = msg.arg1;
                    logD("AddressedPlayer = " + mAddressedPlayerId);

                    // The now playing list is tied to the addressed player by specification in
                    // AVRCP 5.9.1. A new addressed player means our now playing content is now
                    // invalid
                    mBrowseTree.mNowPlayingNode.setCached(false);
                    if (isActive()) {
                        BluetoothMediaBrowserService.notifyChanged(mBrowseTree.mNowPlayingNode);
                    }

                    AvrcpPlayer updatedPlayer = mAvailablePlayerList.get(mAddressedPlayerId);
                    if (updatedPlayer != null) {
                        mAddressedPlayer = updatedPlayer;
                        // If the new player supports the now playing feature then fetch it
                        if (mAddressedPlayer.supportsFeature(AvrcpPlayer.FEATURE_NOW_PLAYING)) {
                            sendMessage(MESSAGE_GET_FOLDER_ITEMS, mBrowseTree.mNowPlayingNode);
                        }
                        logD("AddressedPlayer = " + mAddressedPlayer.getName());
                    } else {
                        logD("Addressed player changed to unknown ID=" + mAddressedPlayerId);
                        mBrowseTree.mRootNode.setCached(false);
                        mBrowseTree.mRootNode.setExpectedChildren(255);
                        BluetoothMediaBrowserService.notifyChanged(mBrowseTree.mRootNode);
+48 −0
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@ import android.support.v4.media.MediaDescriptionCompat;
import android.support.v4.media.MediaMetadataCompat;
import android.util.Log;

import java.util.Objects;

/**
 * An object representing a single item returned from an AVRCP folder listing in the VFS scope.
 *
@@ -105,6 +107,14 @@ public class AvrcpItem {
        return mUuid;
    }

    public int getItemType() {
        return mItemType;
    }

    public int getType() {
        return mType;
    }

    public String getDisplayableName() {
        return mDisplayableName;
    }
@@ -129,6 +139,14 @@ public class AvrcpItem {
        return mTotalNumberOfTracks;
    }

    public String getGenre() {
        return mGenre;
    }

    public long getPlayingTime() {
        return mPlayingTime;
    }

    public boolean isPlayable() {
        return mPlayable;
    }
@@ -211,6 +229,36 @@ public class AvrcpItem {
                + mBrowsable + ", mCoverArtHandle=" + getCoverArtHandle() + "}";
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }

        if (!(o instanceof AvrcpItem)) {
            return false;
        }

        AvrcpItem other = ((AvrcpItem) o);
        return Objects.equals(mUuid, other.getUuid())
                && Objects.equals(mDevice, other.getDevice())
                && Objects.equals(mUid, other.getUid())
                && Objects.equals(mItemType, other.getItemType())
                && Objects.equals(mType, other.getType())
                && Objects.equals(mTitle, other.getTitle())
                && Objects.equals(mDisplayableName, other.getDisplayableName())
                && Objects.equals(mArtistName, other.getArtistName())
                && Objects.equals(mAlbumName, other.getAlbumName())
                && Objects.equals(mTrackNumber, other.getTrackNumber())
                && Objects.equals(mTotalNumberOfTracks, other.getTotalNumberOfTracks())
                && Objects.equals(mGenre, other.getGenre())
                && Objects.equals(mPlayingTime, other.getPlayingTime())
                && Objects.equals(mCoverArtHandle, other.getCoverArtHandle())
                && Objects.equals(mPlayable, other.isPlayable())
                && Objects.equals(mBrowsable, other.isBrowsable())
                && Objects.equals(mImageUri, other.getCoverArtLocation());
    }

    /**
     * Builder for an AvrcpItem
     */
+1 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ class AvrcpPlayer {
    public static final int FEATURE_FORWARD = 47;
    public static final int FEATURE_PREVIOUS = 48;
    public static final int FEATURE_BROWSING = 59;
    public static final int FEATURE_NOW_PLAYING = 65;

    private BluetoothDevice mDevice;
    private int mPlayStatus = PlaybackStateCompat.STATE_NONE;
+126 −9
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ import org.mockito.MockitoAnnotations;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -517,15 +518,71 @@ public class AvrcpControllerStateMachineTest {
    }

    /**
     * Test addressed media player changed
     * Make an AvrcpItem suitable for being included in the Now Playing list for the test device
     */
    private AvrcpItem makeNowPlayingItem(long uid, String name) {
        AvrcpItem.Builder aib = new AvrcpItem.Builder();
        aib.setDevice(mTestDevice);
        aib.setItemType(AvrcpItem.TYPE_MEDIA);
        aib.setType(AvrcpItem.MEDIA_AUDIO);
        aib.setTitle(name);
        aib.setUid(uid);
        aib.setUuid(UUID.randomUUID().toString());
        aib.setPlayable(true);
        return aib.build();
    }

    /**
     * Get the current Now Playing list for the test device
     */
    private List<AvrcpItem> getNowPlayingList() {
        BrowseTree.BrowseNode nowPlaying = mAvrcpStateMachine.findNode("NOW_PLAYING");
        List<AvrcpItem> nowPlayingList = new ArrayList<AvrcpItem>();
        for (BrowseTree.BrowseNode child : nowPlaying.getChildren()) {
            nowPlayingList.add(child.mItem);
        }
        return nowPlayingList;
    }

    /**
     * Set the current Now Playing list for the test device
     */
    private void setNowPlayingList(List<AvrcpItem> nowPlayingList) {
        BrowseTree.BrowseNode nowPlaying = mAvrcpStateMachine.findNode("NOW_PLAYING");
        mAvrcpStateMachine.requestContents(nowPlaying);
        mAvrcpStateMachine.sendMessage(
                AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, nowPlayingList);
        mAvrcpStateMachine.sendMessage(
                AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS_OUT_OF_RANGE);

        // Wait for the now playing list to be propagated
        TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper());

        // Make sure its set by re grabbing the node and checking its contents are cached
        nowPlaying = mAvrcpStateMachine.findNode("NOW_PLAYING");
        Assert.assertTrue(nowPlaying.isCached());
        assertNowPlayingList(nowPlayingList);
    }

    /**
     * Assert that the Now Playing list is a particular value
     */
    private void assertNowPlayingList(List<AvrcpItem> expected) {
        List<AvrcpItem> current = getNowPlayingList();
        Assert.assertEquals(expected.size(), current.size());
        for (int i = 0; i < expected.size(); i++) {
            Assert.assertEquals(expected.get(i), current.get(i));
        }
    }

    /**
     * Test addressed media player changing to a player we know about
     * Verify when the addressed media player changes browsing data updates
     * Verify that the contents of a player are fetched upon request
     */
    @Test
    public void testPlayerChanged() {
        setUpConnectedState(true, true);
        final String rootName = "__ROOT__";
        final String playerName = "Player 1";

        //Get the root of the device
        BrowseTree.BrowseNode results = mAvrcpStateMachine.findNode(rootName);
@@ -538,25 +595,85 @@ public class AvrcpControllerStateMachineTest {
                timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)).getPlayerListNative(eq(mTestAddress),
                eq(0), eq(19));

        //Provide back a player object
        //Provide back two player objects, IDs 1 and 2
        byte[] playerFeatures =
                new byte[]{0, 0, 0, 0, 0, (byte) 0xb7, 0x01, 0x0c, 0x0a, 0, 0, 0, 0, 0, 0, 0};
        AvrcpPlayer playerOne = new AvrcpPlayer(mTestDevice, 1, playerName, playerFeatures, 1, 1);
        AvrcpPlayer playerOne = new AvrcpPlayer(mTestDevice, 1, "Player 1", playerFeatures, 1, 1);
        AvrcpPlayer playerTwo = new AvrcpPlayer(mTestDevice, 2, "Player 2", playerFeatures, 1, 1);
        List<AvrcpPlayer> testPlayers = new ArrayList<>();
        testPlayers.add(playerOne);
        testPlayers.add(playerTwo);
        mAvrcpStateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_PLAYER_ITEMS,
                testPlayers);

        //Set something arbitrary for the current Now Playing list
        List<AvrcpItem> nowPlayingList = new ArrayList<AvrcpItem>();
        nowPlayingList.add(makeNowPlayingItem(1, "Song 1"));
        nowPlayingList.add(makeNowPlayingItem(2, "Song 2"));
        setNowPlayingList(nowPlayingList);

        //Change players and verify that BT attempts to update the results
        mAvrcpStateMachine.sendMessage(
                AvrcpControllerStateMachine.MESSAGE_PROCESS_ADDRESSED_PLAYER_CHANGED, 4);
        results = mAvrcpStateMachine.findNode(rootName);
                AvrcpControllerStateMachine.MESSAGE_PROCESS_ADDRESSED_PLAYER_CHANGED, 2);
        TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper());

        mAvrcpStateMachine.requestContents(results);
        //Make sure the Now Playing list is now cleared
        assertNowPlayingList(new ArrayList<AvrcpItem>());

        //Verify that a player change to a player with Now Playing support causes a refresh. This
        //should be called twice, once to give data and once to ensure we're out of elements
        verify(mAvrcpControllerService,
                timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).getNowPlayingListNative(
                eq(mTestAddress), eq(0), eq(19));
    }

    /**
     * Test addressed media player change to a player we don't know about
     * Verify when the addressed media player changes browsing data updates
     * Verify that the contents of a player are fetched upon request
     */
    @Test
    public void testPlayerChangedToUnknownPlayer() {
        setUpConnectedState(true, true);
        final String rootName = "__ROOT__";

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

        //Request fetch the list of players
        BrowseTree.BrowseNode playerNodes = mAvrcpStateMachine.findNode(rootNode.getID());
        mAvrcpStateMachine.requestContents(rootNode);
        verify(mAvrcpControllerService,
                timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).getPlayerListNative(eq(mTestAddress),
                timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)).getPlayerListNative(eq(mTestAddress),
                eq(0), eq(19));

        //Provide back a player object
        byte[] playerFeatures =
                new byte[]{0, 0, 0, 0, 0, (byte) 0xb7, 0x01, 0x0c, 0x0a, 0, 0, 0, 0, 0, 0, 0};
        AvrcpPlayer playerOne = new AvrcpPlayer(mTestDevice, 1, "Player 1", playerFeatures, 1, 1);
        List<AvrcpPlayer> testPlayers = new ArrayList<>();
        testPlayers.add(playerOne);
        mAvrcpStateMachine.sendMessage(
                AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_PLAYER_ITEMS, testPlayers);

        //Set something arbitrary for the current Now Playing list
        List<AvrcpItem> nowPlayingList = new ArrayList<AvrcpItem>();
        nowPlayingList.add(makeNowPlayingItem(1, "Song 1"));
        nowPlayingList.add(makeNowPlayingItem(2, "Song 2"));
        setNowPlayingList(nowPlayingList);

        //Change players
        mAvrcpStateMachine.sendMessage(
                AvrcpControllerStateMachine.MESSAGE_PROCESS_ADDRESSED_PLAYER_CHANGED, 4);
        TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper());

        //Make sure the Now Playing list is now cleared
        assertNowPlayingList(new ArrayList<AvrcpItem>());

        //Make sure the root node is no longer cached
        rootNode = mAvrcpStateMachine.findNode(rootName);
        Assert.assertFalse(rootNode.isCached());
    }

    /**