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

Commit bae79bec authored by Sal Savage's avatar Sal Savage
Browse files

Add tests for the AVRCP Target Cover Art feature

Tag: #feature
Bug: 153076316
Test: atest BluetoothInstrumentationTests
Change-Id: I6a911e0480b68004fb9182a5d0f03d37b4ce7da2
parent 373eefcf
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import com.android.bluetooth.audio_util.PlayerInfo;
import com.android.bluetooth.btservice.MetricsLogger;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.btservice.ServiceFactory;
import com.android.internal.annotations.VisibleForTesting;

import java.util.List;
import java.util.Objects;
@@ -144,6 +145,14 @@ public class AvrcpTargetService extends ProfileService {
        }
    }

    /**
     * Set the AvrcpTargetService instance.
     */
    @VisibleForTesting
    public static void set(AvrcpTargetService instance) {
        sInstance = instance;
    }

    /**
     * Get the AvrcpTargetService instance. Returns null if the service hasn't been initialized.
     */
+1.57 KiB
Loading image diff...
+1.51 KiB
Loading image diff...
+157 −20
Original line number Diff line number Diff line
@@ -18,15 +18,28 @@ package com.android.bluetooth.audio_util;

import static org.mockito.Mockito.*;

import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaDescription;
import android.media.browse.MediaBrowser.MediaItem;
import android.media.session.PlaybackState;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.test.mock.MockContentProvider;
import android.test.mock.MockContentResolver;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -36,6 +49,7 @@ import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

@@ -53,10 +67,54 @@ public class BrowserPlayerWrapperTest {
    @Mock BrowsedPlayerWrapper.BrowseCallback mBrowseCb;
    private HandlerThread mThread;

    @Mock Context mMockContext;
    private Context mTargetContext;
    private Resources mTestResources;
    private MockContentResolver mTestContentResolver;

    private static final String TEST_AUTHORITY = "com.android.bluetooth.avrcp.test";
    private static final Uri TEST_CONTENT_URI = new Uri.Builder()
            .scheme(ContentResolver.SCHEME_CONTENT)
            .authority(TEST_AUTHORITY)
            .build();

    private static final String IMAGE_HANDLE_1 = "0000001";
    private static final Uri IMAGE_URI_1 = TEST_CONTENT_URI.buildUpon()
            .appendQueryParameter("handle", IMAGE_HANDLE_1)
            .build();
    private static final String IMAGE_STRING_1 = IMAGE_URI_1.toString();

    private Bitmap mTestBitmap = null;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);

        mTargetContext = InstrumentationRegistry.getTargetContext();
        try {
            mTestResources = mTargetContext.getPackageManager()
                    .getResourcesForApplication("com.android.bluetooth.tests");
        } catch (PackageManager.NameNotFoundException e) {
            Assert.fail("Setup Failure Unable to get resources" + e.toString());
        }

        mTestBitmap = loadImage(com.android.bluetooth.tests.R.raw.image_200_200);

        mTestContentResolver = new MockContentResolver(mTargetContext);
        mTestContentResolver.addProvider(TEST_AUTHORITY, new MockContentProvider() {
            @Override
            public AssetFileDescriptor openTypedAssetFile(Uri url, String mimeType, Bundle opts) {
                String handle = url.getQueryParameter("handle");
                if (IMAGE_URI_1.equals(url)) {
                    return mTestResources.openRawResourceFd(
                            com.android.bluetooth.tests.R.raw.image_200_200);
                }
                return null;
            }
        });

        when(mMockContext.getContentResolver()).thenReturn(mTestContentResolver);

        // Set up Looper thread for the timeout handler
        mThread = new HandlerThread("MediaPlayerWrapperTestThread");
        mThread.start();
@@ -66,10 +124,50 @@ public class BrowserPlayerWrapperTest {
        MediaBrowserFactory.inject(mMockBrowser);
    }

    @After
    public void tearDown() {
        if (mThread != null) {
            mThread.quitSafely();
        }
        mThread = null;
        mTestContentResolver = null;
        mTestBitmap = null;
        mTestResources = null;
        mTargetContext = null;
    }

    private Bitmap loadImage(int resId) {
        InputStream imageInputStream = mTestResources.openRawResource(resId);
        return BitmapFactory.decodeStream(imageInputStream);
    }

    private MediaDescription getMediaDescription(String id, String title, String artist,
            String album, Bitmap bitmap, Uri uri, Bundle extras) {
        MediaDescription.Builder builder = new MediaDescription.Builder()
                .setMediaId(id)
                .setTitle(title)
                .setSubtitle(artist)
                .setDescription(album);
        if (bitmap != null) {
            builder.setIconBitmap(bitmap);
        }
        if (uri != null) {
            builder.setIconUri(uri);
        }
        if (extras != null) {
            builder.setExtras(extras);
        }
        return builder.build();
    }

    private MediaItem getMediaItem(MediaDescription description, int flags) {
        return new MediaItem(description, flags);
    }

    @Test
    public void testWrap() {
        BrowsedPlayerWrapper wrapper =
                BrowsedPlayerWrapper.wrap(null, mThread.getLooper(), "test", "test");
                BrowsedPlayerWrapper.wrap(mMockContext, mThread.getLooper(), "test", "test");
        wrapper.connect(mConnCb);
        verify(mMockBrowser).testInit(any(), any(), mBrowserConnCb.capture(), any());
        verify(mMockBrowser).connect();
@@ -84,7 +182,7 @@ public class BrowserPlayerWrapperTest {
    @Test
    public void testConnect_Successful() {
        BrowsedPlayerWrapper wrapper =
                BrowsedPlayerWrapper.wrap(null, mThread.getLooper(), "test", "test");
                BrowsedPlayerWrapper.wrap(mMockContext, mThread.getLooper(), "test", "test");
        wrapper.connect(mConnCb);
        verify(mMockBrowser).testInit(any(), any(), mBrowserConnCb.capture(), any());
        MediaBrowser.ConnectionCallback browserConnCb = mBrowserConnCb.getValue();
@@ -98,7 +196,7 @@ public class BrowserPlayerWrapperTest {
    @Test
    public void testConnect_Suspended() {
        BrowsedPlayerWrapper wrapper =
                BrowsedPlayerWrapper.wrap(null, mThread.getLooper(), "test", "test");
                BrowsedPlayerWrapper.wrap(mMockContext, mThread.getLooper(), "test", "test");
        wrapper.connect(mConnCb);
        verify(mMockBrowser).testInit(any(), any(), mBrowserConnCb.capture(), any());
        MediaBrowser.ConnectionCallback browserConnCb = mBrowserConnCb.getValue();
@@ -115,7 +213,7 @@ public class BrowserPlayerWrapperTest {
    @Test
    public void testConnect_Failed() {
        BrowsedPlayerWrapper wrapper =
                BrowsedPlayerWrapper.wrap(null, mThread.getLooper(), "test", "test");
                BrowsedPlayerWrapper.wrap(mMockContext, mThread.getLooper(), "test", "test");
        wrapper.connect(mConnCb);
        verify(mMockBrowser).testInit(any(), any(), mBrowserConnCb.capture(), any());
        MediaBrowser.ConnectionCallback browserConnCb = mBrowserConnCb.getValue();
@@ -129,7 +227,7 @@ public class BrowserPlayerWrapperTest {
    @Test
    public void testEmptyRoot() {
        BrowsedPlayerWrapper wrapper =
                BrowsedPlayerWrapper.wrap(null, mThread.getLooper(), "test", "test");
                BrowsedPlayerWrapper.wrap(mMockContext, mThread.getLooper(), "test", "test");

        doReturn("").when(mMockBrowser).getRoot();

@@ -147,7 +245,7 @@ public class BrowserPlayerWrapperTest {
    @Test
    public void testDisconnect() {
        BrowsedPlayerWrapper wrapper =
                BrowsedPlayerWrapper.wrap(null, mThread.getLooper(), "test", "test");
                BrowsedPlayerWrapper.wrap(mMockContext, mThread.getLooper(), "test", "test");
        wrapper.connect(mConnCb);
        verify(mMockBrowser).testInit(any(), any(), mBrowserConnCb.capture(), any());
        MediaBrowser.ConnectionCallback browserConnCb = mBrowserConnCb.getValue();
@@ -158,7 +256,7 @@ public class BrowserPlayerWrapperTest {
    @Test
    public void testGetRootId() {
        BrowsedPlayerWrapper wrapper =
                BrowsedPlayerWrapper.wrap(null, mThread.getLooper(), "test", "test");
                BrowsedPlayerWrapper.wrap(mMockContext, mThread.getLooper(), "test", "test");
        wrapper.connect(mConnCb);
        verify(mMockBrowser).testInit(any(), any(), mBrowserConnCb.capture(), any());
        MediaBrowser.ConnectionCallback browserConnCb = mBrowserConnCb.getValue();
@@ -171,7 +269,7 @@ public class BrowserPlayerWrapperTest {
    @Test
    public void testPlayItem() {
        BrowsedPlayerWrapper wrapper =
                BrowsedPlayerWrapper.wrap(null, mThread.getLooper(), "test", "test");
                BrowsedPlayerWrapper.wrap(mMockContext, mThread.getLooper(), "test", "test");
        verify(mMockBrowser).testInit(any(), any(), mBrowserConnCb.capture(), any());
        MediaBrowser.ConnectionCallback browserConnCb = mBrowserConnCb.getValue();

@@ -208,7 +306,7 @@ public class BrowserPlayerWrapperTest {
    @Test
    public void testPlayItem_Timeout() {
        BrowsedPlayerWrapper wrapper =
                BrowsedPlayerWrapper.wrap(null, mThread.getLooper(), "test", "test");
                BrowsedPlayerWrapper.wrap(mMockContext, mThread.getLooper(), "test", "test");
        verify(mMockBrowser).testInit(any(), any(), mBrowserConnCb.capture(), any());
        MediaBrowser.ConnectionCallback browserConnCb = mBrowserConnCb.getValue();

@@ -235,35 +333,74 @@ public class BrowserPlayerWrapperTest {
    @Test
    public void testGetFolderItems() {
        BrowsedPlayerWrapper wrapper =
                BrowsedPlayerWrapper.wrap(null, mThread.getLooper(), "test", "test");
                BrowsedPlayerWrapper.wrap(mMockContext, mThread.getLooper(), "test", "test");
        verify(mMockBrowser).testInit(any(), any(), mBrowserConnCb.capture(), any());
        MediaBrowser.ConnectionCallback browserConnCb = mBrowserConnCb.getValue();

        wrapper.getFolderItems("test_folder", mBrowseCb);


        browserConnCb.onConnected();
        verify(mMockBrowser).subscribe(any(), mSubscriptionCb.capture());
        MediaBrowser.SubscriptionCallback subscriptionCb = mSubscriptionCb.getValue();

        MediaDescription desc = null;
        ArrayList<MediaItem> items = new ArrayList<MediaItem>();
        MediaDescription.Builder bob = new MediaDescription.Builder();
        bob.setTitle("test_song1");
        bob.setMediaId("ts1");
        items.add(new MediaItem(bob.build(), 0));
        bob.setTitle("test_song2");
        bob.setMediaId("ts2");
        items.add(new MediaItem(bob.build(), 0));

        desc = getMediaDescription("s1", "song1", "artist", "album", null, null, null);
        items.add(getMediaItem(desc, MediaItem.FLAG_PLAYABLE));

        desc = getMediaDescription("s2", "song2", "artist", "album", mTestBitmap, null, null);
        items.add(getMediaItem(desc, MediaItem.FLAG_PLAYABLE));

        desc = getMediaDescription("s3", "song3", "artist", "album", null, IMAGE_URI_1, null);
        items.add(getMediaItem(desc, MediaItem.FLAG_PLAYABLE));

        desc = getMediaDescription("a1", "album1", "artist", null, null, null, null);
        items.add(getMediaItem(desc, MediaItem.FLAG_BROWSABLE));

        desc = getMediaDescription("a2", "album2", "artist", null, mTestBitmap, null, null);
        items.add(getMediaItem(desc, MediaItem.FLAG_BROWSABLE));

        desc = getMediaDescription("a3", "album3", "artist", null, null, IMAGE_URI_1, null);
        items.add(getMediaItem(desc, MediaItem.FLAG_BROWSABLE));

        desc = getMediaDescription("p1", "playlist1", null, null, mTestBitmap, null, null);
        items.add(getMediaItem(desc, MediaItem.FLAG_BROWSABLE | MediaItem.FLAG_PLAYABLE));

        subscriptionCb.onChildrenLoaded("test_folder", items);
        verify(mMockBrowser).unsubscribe(eq("test_folder"));
        verify(mBrowseCb).run(eq(BrowsedPlayerWrapper.STATUS_SUCCESS), eq("test_folder"),
                mWrapperBrowseCb.capture());

        // Verify returned ListItems
        List<ListItem> item_list = mWrapperBrowseCb.getValue();
        for (int i = 0; i < item_list.size(); i++) {
            Assert.assertFalse(item_list.get(i).isFolder);
            Assert.assertEquals(item_list.get(i).song, Util.toMetadata(items.get(i)));
            MediaItem expected = items.get(i);
            ListItem item = item_list.get(i);
            Assert.assertEquals(expected.isBrowsable(), item.isFolder);
            if (item.isFolder) {
                Folder folder = item.folder;
                Assert.assertNotNull(folder);
                Assert.assertFalse(folder.isPlayable);
                Assert.assertEquals(expected.getDescription().getMediaId(), folder.mediaId);
                Assert.assertEquals(expected.getDescription().getTitle(), folder.title);
            } else {
                Metadata song = item.song;
                Assert.assertNotNull(song);
                Assert.assertEquals(expected.getDescription().getMediaId(), song.mediaId);
                Assert.assertEquals(expected.getDescription().getTitle(), song.title);
                Assert.assertEquals(expected.getDescription().getSubtitle(), song.artist);
                Assert.assertEquals(expected.getDescription().getDescription(), song.album);
                if (expected.getDescription().getIconBitmap() != null) {
                    Assert.assertNotNull(song.image);
                    Bitmap expectedBitmap = expected.getDescription().getIconBitmap();
                    Assert.assertTrue(expectedBitmap.sameAs(song.image.getImage()));
                } else if (expected.getDescription().getIconUri() != null) {
                    Assert.assertTrue(mTestBitmap.sameAs(song.image.getImage()));
                } else {
                    Assert.assertEquals(null, song.image);
                }
            }
        }

        verify(mMockBrowser).disconnect();
+454 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading