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

Commit e429133e authored by Sal Savage's avatar Sal Savage Committed by Gerrit Code Review
Browse files

Merge changes I525d8f3b,I5ea7b355 into main

* changes:
  Refactor some Bluetooth Media related logging
  Update playback state when track changes
parents 2f997083 b9f33066
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -134,6 +134,7 @@ public class A2dpSinkService extends ProfileService {
     * Set the device that should be allowed to actively stream
     */
    public boolean setActiveDevice(BluetoothDevice device) {
        Log.i(TAG, "setActiveDevice(device=" + device + ")");
        synchronized (mActiveDeviceLock) {
            if (mNativeInterface.setActiveDevice(device)) {
                mActiveDevice = device;
+19 −4
Original line number Diff line number Diff line
@@ -208,8 +208,12 @@ public class AvrcpControllerService extends ProfileService {
     */
    @VisibleForTesting
    boolean setActiveDevice(BluetoothDevice device) {
        if (DBG) {
            Log.d(TAG, "setActiveDevice(device=" + device + ")");
        }
        A2dpSinkService a2dpSinkService = A2dpSinkService.getA2dpSinkService();
        if (a2dpSinkService == null) {
            Log.w(TAG, "setActiveDevice(device=" + device + "): A2DP Sink not available");
            return false;
        }

@@ -242,6 +246,8 @@ public class AvrcpControllerService extends ProfileService {
                return true;
            }
        }

        Log.w(TAG, "setActiveDevice(device=" + device + "): A2DP Sink request failed");
        return false;
    }

@@ -333,15 +339,21 @@ public class AvrcpControllerService extends ProfileService {
            for (AvrcpControllerStateMachine stateMachine : mDeviceStateMap.values()) {
                requestedNode = stateMachine.findNode(parentMediaId);
                if (requestedNode != null) {
                    Log.d(TAG, "Found a node");
                    break;
                }
            }
        }

        if (DBG) {
            Log.d(TAG, "getContents(" + parentMediaId + "): "
                    + (requestedNode == null
                            ? "Failed to find node"
                            : "node=" + requestedNode + ", device=" + requestedNode.getDevice()));
        }

        // If we don't find a node in the tree then do not have any way to browse for the contents.
        // Return an empty list instead.
        if (requestedNode == null) {
            if (DBG) Log.d(TAG, "Didn't find a node");
            return new BrowseResult(new ArrayList(0), BrowseResult.ERROR_MEDIA_ID_INVALID);
        }
        if (parentMediaId.equals(BrowseTree.ROOT) && requestedNode.getChildrenCount() == 0) {
@@ -355,9 +367,8 @@ public class AvrcpControllerService extends ProfileService {

        List<MediaItem> contents = requestedNode.getContents();

        if (DBG) Log.d(TAG, "Returning contents");
        if (!requestedNode.isCached()) {
            if (DBG) Log.d(TAG, "node is not cached");
            if (DBG) Log.d(TAG, "getContents(" + parentMediaId + "): node download pending");
            refreshContents(requestedNode);
            /* Ongoing downloads can have partial results and we want to make sure they get sent
             * to the client. If a download gets kicked off as a result of this request, the
@@ -365,6 +376,10 @@ public class AvrcpControllerService extends ProfileService {
             */
            return new BrowseResult(contents, BrowseResult.DOWNLOAD_PENDING);
        }
        if (DBG) {
            Log.d(TAG, "getContents(" + parentMediaId + "): return node, contents="
                    + requestedNode.getContents());
        }
        return new BrowseResult(contents, BrowseResult.SUCCESS);
    }

+2 −0
Original line number Diff line number Diff line
@@ -581,6 +581,8 @@ class AvrcpControllerStateMachine extends StateMachine {
                    mAddressedPlayer.updateCurrentTrack(track);
                    if (isActive()) {
                        BluetoothMediaBrowserService.trackChanged(track);
                        BluetoothMediaBrowserService.notifyChanged(
                                mAddressedPlayer.getPlaybackState());
                    }
                    if (previousTrack != null) {
                        removeUnusedArtwork(previousTrack.getCoverArtUuid());
+20 −14
Original line number Diff line number Diff line
@@ -86,6 +86,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(Intent.ACTION_LOCALE_CHANGED)) {
                if (DBG) Log.d(TAG, "Locale has updated");
                if (sBluetoothMediaBrowserService == null) return;
                MediaSessionCompat session = sBluetoothMediaBrowserService.getSession();
                MediaControllerCompat controller = session.getController();
@@ -106,7 +107,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
     */
    @Override
    public void onCreate() {
        if (DBG) Log.d(TAG, "onCreate");
        if (DBG) Log.d(TAG, "Service Created");
        super.onCreate();

        // Create and configure the MediaSessionCompat
@@ -128,6 +129,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {

    @Override
    public void onDestroy() {
        if (DBG) Log.d(TAG, "Service Destroyed");
        unregisterReceiver(mReceiver);
        mReceiver = null;
    }
@@ -191,6 +193,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
        AvrcpControllerService avrcpControllerService =
                AvrcpControllerService.getAvrcpControllerService();
        if (avrcpControllerService == null) {
            Log.w(TAG, "getContents(id=" + parentMediaId + "): AVRCP Controller Service not ready");
            return new BrowseResult(new ArrayList(0), BrowseResult.ERROR_NO_AVRCP_SERVICE);
        } else {
            return avrcpControllerService.getContents(parentMediaId);
@@ -227,7 +230,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
    @Override
    public synchronized void onLoadChildren(final String parentMediaId,
            final Result<List<MediaItem>> result) {
        if (DBG) Log.d(TAG, "onLoadChildren parentMediaId= " + parentMediaId);
        if (DBG) Log.d(TAG, "Request for contents, id= " + parentMediaId);
        BrowseResult contents = getContents(parentMediaId);
        byte status = contents.getStatus();
        List<MediaItem> results = contents.getResults();
@@ -236,8 +239,8 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
            result.detach();
        } else {
            if (DBG) {
                Log.d(TAG, "id= " + parentMediaId + ", status= " + contents.getStatusString()
                        + ", results=" + results);
                Log.d(TAG, "Received Contents, id= " + parentMediaId + ", status= "
                        + contents.getStatusString() + ", results=" + results);
            }
            result.sendResult(results);
        }
@@ -245,7 +248,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {

    @Override
    public BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) {
        if (DBG) Log.d(TAG, "onGetRoot");
        Log.i(TAG, "Browser Client Connection Request, client='" + clientPackageName + "')");
        Bundle style = getDefaultStyle();
        return new BrowserRoot(BrowseTree.ROOT, style);
    }
@@ -263,6 +266,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
        } else {
            mSession.setQueue(null);
        }
        if (DBG) Log.d(TAG, "Now Playing List Changed, queue=" + mMediaQueue);
    }

    private void clearNowPlayingQueue() {
@@ -275,6 +279,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
            if (node.getScope() == AvrcpControllerService.BROWSE_SCOPE_NOW_PLAYING) {
                sBluetoothMediaBrowserService.updateNowPlayingQueue(node);
            } else {
                if (DBG) Log.d(TAG, "Browse Node contents changed, node=" + node);
                sBluetoothMediaBrowserService.notifyChildrenChanged(node.getID());
            }
        }
@@ -293,7 +298,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
    }

    static synchronized void trackChanged(AvrcpItem track) {
        if (DBG) Log.d(TAG, "trackChanged setMetadata=" + track);
        if (DBG) Log.d(TAG, "Track Changed, track=" + track);
        if (sBluetoothMediaBrowserService != null) {
            if (track != null) {
                sBluetoothMediaBrowserService.mSession.setMetadata(track.toMediaMetadata());
@@ -307,7 +312,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
    }

    static synchronized void notifyChanged(PlaybackStateCompat playbackState) {
        Log.d(TAG, "notifyChanged PlaybackState" + playbackState);
        if (DBG) Log.d(TAG, "Playback State Changed, state=" + playbackState);
        if (sBluetoothMediaBrowserService != null) {
            sBluetoothMediaBrowserService.mSession.setPlaybackState(playbackState);
        } else {
@@ -340,15 +345,16 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
    /**
     * Get playback state
     */
    public static synchronized int getPlaybackState() {
    public static synchronized PlaybackStateCompat getPlaybackState() {
        if (sBluetoothMediaBrowserService != null) {
            PlaybackStateCompat currentPlaybackState =
                    sBluetoothMediaBrowserService.mSession.getController().getPlaybackState();
            if (currentPlaybackState != null) {
                return currentPlaybackState.getState();
            }
            MediaSessionCompat session = sBluetoothMediaBrowserService.getSession();
            if (session == null) return null;
            MediaControllerCompat controller = session.getController();
            PlaybackStateCompat playbackState =
                    controller == null ? null : controller.getPlaybackState();
            return playbackState;
        }
        return PlaybackStateCompat.STATE_ERROR;
        return null;
    }

    /**
+66 −3
Original line number Diff line number Diff line
@@ -405,7 +405,7 @@ public class AvrcpControllerStateMachineTest {
                BluetoothMediaBrowserService.getTransportControls();
        Assert.assertNotNull(transportControls);
        Assert.assertEquals(PlaybackStateCompat.STATE_NONE,
                BluetoothMediaBrowserService.getPlaybackState());
                BluetoothMediaBrowserService.getPlaybackState().getState());
        mAvrcpStateMachine.disconnect();
        numBroadcastsSent += 2;
        verify(mAvrcpControllerService,
@@ -434,7 +434,7 @@ public class AvrcpControllerStateMachineTest {
        int numBroadcastsSent = setUpConnectedState(false, true);
        Assert.assertEquals(1, mAvrcpControllerService.sBrowseTree.mRootNode.getChildrenCount());
        Assert.assertEquals(PlaybackStateCompat.STATE_NONE,
                BluetoothMediaBrowserService.getPlaybackState());
                BluetoothMediaBrowserService.getPlaybackState().getState());
        mAvrcpStateMachine.disconnect();
        numBroadcastsSent += 2;
        verify(mAvrcpControllerService,
@@ -1268,6 +1268,69 @@ public class AvrcpControllerStateMachineTest {
        Assert.assertFalse(mAvrcpStateMachine.isActive());
    }

    @Test
    public void testTrackChangedWhileActive_currentTrackAndQueueNumberUpdated() {
        setUpConnectedState(true, true);

        // Set track
        AvrcpItem track = makeTrack("Song 1", "artist", "album", 1, 2, "none", 10, null);
        setCurrentTrack(track);

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

        // Set playing
        setPlaybackState(PlaybackStateCompat.STATE_PLAYING);

        // Wait
        TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper());

        // Verify track and playback state
        MediaSessionCompat session = BluetoothMediaBrowserService.getSession();
        Assert.assertNotNull(session);
        MediaControllerCompat controller = session.getController();
        Assert.assertNotNull(controller);

        MediaMetadataCompat metadata = controller.getMetadata();
        Assert.assertNotNull(metadata);
        Assert.assertEquals("Song 1", metadata.getString(MediaMetadataCompat.METADATA_KEY_TITLE));
        Assert.assertEquals("artist", metadata.getString(MediaMetadataCompat.METADATA_KEY_ARTIST));
        Assert.assertEquals("album", metadata.getString(MediaMetadataCompat.METADATA_KEY_ALBUM));
        Assert.assertEquals(1, metadata.getLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER));
        Assert.assertEquals(2, metadata.getLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS));
        Assert.assertEquals("none", metadata.getString(MediaMetadataCompat.METADATA_KEY_GENRE));
        Assert.assertEquals(10, metadata.getLong(MediaMetadataCompat.METADATA_KEY_DURATION));

        PlaybackStateCompat playbackState = controller.getPlaybackState();
        Assert.assertNotNull(playbackState);
        Assert.assertEquals(PlaybackStateCompat.STATE_PLAYING, playbackState.getState());
        Assert.assertEquals(0, playbackState.getActiveQueueItemId());

        // Track changes, with new metadata and new track number
        track = makeTrack("Song 2", "artist", "album", 2, 2, "none", 10, null);
        setCurrentTrack(track);
        TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper());

        // Assert new track metadata and active queue item
        metadata = controller.getMetadata();
        Assert.assertNotNull(metadata);
        Assert.assertEquals("Song 2", metadata.getString(MediaMetadataCompat.METADATA_KEY_TITLE));
        Assert.assertEquals("artist", metadata.getString(MediaMetadataCompat.METADATA_KEY_ARTIST));
        Assert.assertEquals("album", metadata.getString(MediaMetadataCompat.METADATA_KEY_ALBUM));
        Assert.assertEquals(2, metadata.getLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER));
        Assert.assertEquals(2, metadata.getLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS));
        Assert.assertEquals("none", metadata.getString(MediaMetadataCompat.METADATA_KEY_GENRE));
        Assert.assertEquals(10, metadata.getLong(MediaMetadataCompat.METADATA_KEY_DURATION));

        playbackState = controller.getPlaybackState();
        Assert.assertNotNull(playbackState);
        Assert.assertEquals(PlaybackStateCompat.STATE_PLAYING, playbackState.getState());
        Assert.assertEquals(1, playbackState.getActiveQueueItemId());
    }

    /**
     * Test receiving a track change update when we're not the active device
     */
@@ -1318,7 +1381,7 @@ public class AvrcpControllerStateMachineTest {
                eq(mTestAddress), eq(AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE), eq(KEY_DOWN));
        verify(mA2dpSinkService, never()).requestAudioFocus(mTestDevice, true);
        Assert.assertEquals(PlaybackStateCompat.STATE_ERROR,
                BluetoothMediaBrowserService.getPlaybackState());
                BluetoothMediaBrowserService.getPlaybackState().getState());
    }

    /**