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

Commit ae919fda authored by Myles Watson's avatar Myles Watson Committed by Xin Li
Browse files

Avrcp: Sync mirror-aosp-master and stage-aosp-master

There is a delta between mirror-aosp-master and stage-aosp-master.

This is probably due to a large number of commits being merged at once
by the auto-merger.  This CL synchronizes the two branches again.

Test: git diff
Change-Id: I9d30d162a13fb6416f3b4140aa5238f7e0e928f2
parent 73617adc
Loading
Loading
Loading
Loading
+35 −63
Original line number Diff line number Diff line
@@ -57,14 +57,12 @@ public class AddressedMediaPlayer {
    private final List<MediaSession.QueueItem> mEmptyNowPlayingList;

    private long mLastTrackIdSent;
    private boolean mNowPlayingListUpdated;

    public AddressedMediaPlayer(AvrcpMediaRspInterface mediaInterface) {
        mEmptyNowPlayingList = new ArrayList<MediaSession.QueueItem>();
        mNowPlayingList = mEmptyNowPlayingList;
        mMediaInterface = mediaInterface;
        mLastTrackIdSent = MediaSession.QueueItem.UNKNOWN_ID;
        mNowPlayingListUpdated = false;
    }

    void cleanup() {
@@ -72,7 +70,6 @@ public class AddressedMediaPlayer {
        mNowPlayingList = mEmptyNowPlayingList;
        mMediaInterface = null;
        mLastTrackIdSent = MediaSession.QueueItem.UNKNOWN_ID;
        mNowPlayingListUpdated = false;
    }

    /* get now playing list from addressed player */
@@ -84,7 +81,7 @@ public class AddressedMediaPlayer {
            mMediaInterface.folderItemsRsp(bdaddr, AvrcpConstants.RSP_NO_AVBL_PLAY, null);
            return;
        }
        List<MediaSession.QueueItem> items = getNowPlayingList(mediaController);
        List<MediaSession.QueueItem> items = updateNowPlayingList(mediaController);
        getFolderItemsFilterAttr(bdaddr, reqObj, items, AvrcpConstants.BTRC_SCOPE_NOW_PLAYING,
                reqObj.mStartItem, reqObj.mEndItem, mediaController);
    }
@@ -94,17 +91,17 @@ public class AddressedMediaPlayer {
            @Nullable MediaController mediaController) {
        int status = AvrcpConstants.RSP_NO_ERROR;
        long mediaId = ByteBuffer.wrap(itemAttr.mUid).getLong();
        List<MediaSession.QueueItem> items = getNowPlayingList(mediaController);
        List<MediaSession.QueueItem> items = updateNowPlayingList(mediaController);

        // NOTE: this is out-of-spec (AVRCP 1.6.1 sec 6.10.4.3, p90) but we answer it anyway
        // because some CTs ask for it.
        if (Arrays.equals(itemAttr.mUid, AvrcpConstants.TRACK_IS_SELECTED)) {
            if (DEBUG) Log.d(TAG, "getItemAttr: Remote requests for now playing contents:");

            // get the current playing metadata and send.
            getItemAttrFilterAttr(bdaddr, itemAttr, getCurrentQueueItem(mediaController, mediaId),
                    mediaController);
            return;
            mediaId = getActiveQueueItemId(mediaController);
            if (DEBUG) {
                Log.d(TAG,
                        "getItemAttr: Remote requests for now playing contents, sending UID: "
                                + mediaId);
            }
        }

        if (DEBUG) Log.d(TAG, "getItemAttr-UID: 0x" + Utils.byteArrayToString(itemAttr.mUid));
@@ -121,51 +118,17 @@ public class AddressedMediaPlayer {

    /* Refresh and get the queue of now playing.
     */
    private @NonNull List<MediaSession.QueueItem> getNowPlayingList(
            @Nullable MediaController mediaController) {
    @NonNull
    List<MediaSession.QueueItem> updateNowPlayingList(@Nullable MediaController mediaController) {
        if (mediaController == null) return mEmptyNowPlayingList;
        List<MediaSession.QueueItem> items = mediaController.getQueue();
        if (items != null && !mNowPlayingListUpdated) {
            mNowPlayingList = items;
            return mNowPlayingList;
        }
        if (items == null) {
            Log.i(TAG, "null queue from " + mediaController.getPackageName()
                            + ", constructing single-item list");
            MediaMetadata metadata = mediaController.getMetadata();

            // Because we are database-unaware, we can just number the item here whatever we want
            // because they have to re-poll it every time.
            MediaSession.QueueItem current = getCurrentQueueItem(mediaController, SINGLE_QID);
            items = new ArrayList<MediaSession.QueueItem>();
            items.add(current);
        }

        mNowPlayingList = items;

        if (mNowPlayingListUpdated) sendNowPlayingListChanged();

        return mNowPlayingList;
    }

    private void sendNowPlayingListChanged() {
        if (mMediaInterface == null) return;
        mMediaInterface.uidsChangedRsp(AvrcpConstants.NOTIFICATION_TYPE_CHANGED);
        mMediaInterface.nowPlayingChangedRsp(AvrcpConstants.NOTIFICATION_TYPE_CHANGED);
        mNowPlayingListUpdated = false;
    }

    /* Constructs a queue item representing the current playing metadata from an
     * active controller with queue id |qid|.
     */
    private MediaSession.QueueItem getCurrentQueueItem(
            @Nullable MediaController controller, long qid) {
        if (controller == null) {
            MediaDescription.Builder bob = new MediaDescription.Builder();
            bob.setTitle(UNKNOWN_TITLE);
            return new QueueItem(bob.build(), qid);
        }

        MediaMetadata metadata = controller.getMetadata();
            MediaMetadata metadata = mediaController.getMetadata();
            if (metadata == null) {
                Log.w(TAG, "Controller has no metadata!? Making an empty one");
                metadata = (new MediaMetadata.Builder()).build();
@@ -183,8 +146,22 @@ public class AddressedMediaPlayer {
            bob.setExtras(fillBundle(metadata, desc.getExtras()));

            // build queue item with the new metadata
        desc = bob.build();
        return new QueueItem(desc, qid);
            MediaSession.QueueItem current = new QueueItem(bob.build(), SINGLE_QID);

            items = new ArrayList<MediaSession.QueueItem>();
            items.add(current);
        }

        if (!items.equals(mNowPlayingList)) sendNowPlayingListChanged();
        mNowPlayingList = items;

        return mNowPlayingList;
    }

    private void sendNowPlayingListChanged() {
        if (mMediaInterface == null) return;
        if (DEBUG) Log.d(TAG, "sendNowPlayingListChanged()");
        mMediaInterface.nowPlayingChangedRsp(AvrcpConstants.NOTIFICATION_TYPE_CHANGED);
    }

    private Bundle fillBundle(MediaMetadata metadata, Bundle currentExtras) {
@@ -211,15 +188,10 @@ public class AddressedMediaPlayer {
        return bundle;
    }

    void updateNowPlayingList(@Nullable MediaController mediaController) {
        mNowPlayingListUpdated = true;
        getNowPlayingList(mediaController);
    }

    /* Instructs media player to play particular media item */
    void playItem(byte[] bdaddr, byte[] uid, @Nullable MediaController mediaController) {
        long qid = ByteBuffer.wrap(uid).getLong();
        List<MediaSession.QueueItem> items = getNowPlayingList(mediaController);
        List<MediaSession.QueueItem> items = updateNowPlayingList(mediaController);

        if (mediaController == null) {
            Log.e(TAG, "No mediaController when PlayItem " + qid + " requested");
@@ -250,7 +222,7 @@ public class AddressedMediaPlayer {
    }

    void getTotalNumOfItems(byte[] bdaddr, @Nullable MediaController mediaController) {
        List<MediaSession.QueueItem> items = getNowPlayingList(mediaController);
        List<MediaSession.QueueItem> items = updateNowPlayingList(mediaController);
        if (DEBUG) Log.d(TAG, "getTotalNumOfItems: " + items.size() + " items.");
        mMediaInterface.getTotalNumOfItemsRsp(bdaddr, AvrcpConstants.RSP_NO_ERROR, 0, items.size());
    }
+56 −47
Original line number Diff line number Diff line
@@ -378,13 +378,13 @@ public final class Avrcp {
        @Override
        public void onMetadataChanged(MediaMetadata metadata) {
            if (DEBUG) Log.v(TAG, "onMetadataChanged");
            updateCurrentMediaState(false);
            updateCurrentMediaState();
        }
        @Override
        public synchronized void onPlaybackStateChanged(PlaybackState state) {
            if (DEBUG) Log.v(TAG, "onPlaybackStateChanged: state " + state.toString());

            updateCurrentMediaState(false);
            updateCurrentMediaState();
        }

        @Override
@@ -487,7 +487,7 @@ public final class Avrcp {
            case MSG_NOW_PLAYING_CHANGED_RSP:
                if (DEBUG) Log.v(TAG, "MSG_NOW_PLAYING_CHANGED_RSP");
                removeMessages(MSG_NOW_PLAYING_CHANGED_RSP);
                updateCurrentMediaState(false);
                updateCurrentMediaState();
                break;

            case MSG_PLAY_INTERVAL_TIMEOUT:
@@ -701,7 +701,7 @@ public final class Avrcp {
            case MSG_SET_A2DP_AUDIO_STATE:
                if (DEBUG) Log.v(TAG, "MSG_SET_A2DP_AUDIO_STATE:" + msg.arg1);
                mA2dpState = msg.arg1;
                updateCurrentMediaState(false);
                updateCurrentMediaState();
                break;

            case MSG_NATIVE_REQ_GET_FOLDER_ITEMS: {
@@ -972,36 +972,8 @@ public final class Avrcp {
        }
    }

    private void updateCurrentMediaState(boolean registering) {
    private void updateCurrentMediaState() {
        // Only do player updates when we aren't registering for track changes.
        if (!registering) {
            if (mAvailablePlayerViewChanged) {
                registerNotificationRspAvalPlayerChangedNative(
                        AvrcpConstants.NOTIFICATION_TYPE_CHANGED);
                mAvailablePlayerViewChanged = false;
                return;
            }
            if (mAddrPlayerChangedNT == AvrcpConstants.NOTIFICATION_TYPE_INTERIM
                    && mReportedPlayerID != mCurrAddrPlayerID) {
                registerNotificationRspAvalPlayerChangedNative(
                        AvrcpConstants.NOTIFICATION_TYPE_CHANGED);
                mAvailablePlayerViewChanged = false;
                registerNotificationRspAddrPlayerChangedNative(
                        AvrcpConstants.NOTIFICATION_TYPE_CHANGED, mCurrAddrPlayerID, sUIDCounter);
                mAddrPlayerChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
                // Changing player sends reject to anything else we would notify...
                mReportedPlayerID = mCurrAddrPlayerID;
                mPlayStatusChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
                mTrackChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
                mPlayPosChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
                mNowPlayingListChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
                mAddressedMediaPlayer.updateNowPlayingList(mMediaController);
                // If the player changed, they need to re-request anything here again
                // so we can skip the rest of the update.
                return;
            }
        }

        MediaAttributes currentAttributes;
        PlaybackState newState = updatePlaybackState();

@@ -1023,6 +995,30 @@ public final class Avrcp {
                            + currentAttributes.toRedactedString() + " : "
                            + mMediaAttributes.toRedactedString());

            if (mAvailablePlayerViewChanged) {
                registerNotificationRspAvalPlayerChangedNative(
                        AvrcpConstants.NOTIFICATION_TYPE_CHANGED);
                mAvailablePlayerViewChanged = false;
                return;
            }

            if (mAddrPlayerChangedNT == AvrcpConstants.NOTIFICATION_TYPE_INTERIM
                    && mReportedPlayerID != mCurrAddrPlayerID) {
                registerNotificationRspAvalPlayerChangedNative(
                        AvrcpConstants.NOTIFICATION_TYPE_CHANGED);
                registerNotificationRspAddrPlayerChangedNative(
                        AvrcpConstants.NOTIFICATION_TYPE_CHANGED, mCurrAddrPlayerID, sUIDCounter);

                mAvailablePlayerViewChanged = false;
                mAddrPlayerChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
                mReportedPlayerID = mCurrAddrPlayerID;

                // Update the now playing list without sending the notification
                mNowPlayingListChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
                mAddressedMediaPlayer.updateNowPlayingList(mMediaController);
                mNowPlayingListChangedNT = AvrcpConstants.NOTIFICATION_TYPE_INTERIM;
            }

            // Dont send now playing list changed if the player doesn't support browsing
            MediaPlayerInfo info = getAddressedPlayerInfo();
            if (info != null && info.isBrowseSupported()) {
@@ -1039,21 +1035,25 @@ public final class Avrcp {
                // to update their metadata. Hold of on sending the playback state
                // update until after we know the current metadata is up to date
                // and track changed has been sent. This was seen on BMW carkits
                Log.i(TAG, "Waiting for metadata update to send track changed");
                Log.i(TAG,
                        "Waiting for metadata update to send track changed: " + newQueueId + " : "
                                + currentAttributes + " : " + mMediaAttributes);

                return;
            }

            // Notify track changed if:
            //  - The CT is registering for the notification
            //  - The CT is registered for the notification
            //  - Queue ID is UNKNOWN and MediaMetadata is different
            //  - Queue ID is valid and different and MediaMetadata is different
            if (registering || ((newQueueId == -1 || newQueueId != mLastQueueId)
                                       && !currentAttributes.equals(mMediaAttributes))) {
            //  - Queue ID is valid and different from last Queue ID sent
            if ((newQueueId == -1 || newQueueId != mLastQueueId)
                    && mTrackChangedNT == AvrcpConstants.NOTIFICATION_TYPE_INTERIM
                    && !currentAttributes.equals(mMediaAttributes)
                    && newPlayStatus == PLAYSTATUS_PLAYING) {
                Log.v(TAG, "Send track changed");
                mMediaAttributes = currentAttributes;
                mLastQueueId = newQueueId;
                sendTrackChangedRsp(registering);
                sendTrackChangedRsp(false);
            }
        } else {
            Log.i(TAG, "Skipping update due to invalid playback state");
@@ -1641,7 +1641,7 @@ public final class Avrcp {
                            Log.v(TAG, "No addressed player but active sessions, taking first.");
                        setAddressedMediaSessionPackage(newControllers.get(0).getPackageName());
                    }
                    updateCurrentMediaState(false);
                    updateCurrentMediaState();
                }
            };

@@ -1661,7 +1661,7 @@ public final class Avrcp {
        // If the player doesn't exist, we need to add it.
        if (getMediaPlayerInfo(packageName) == null) {
            addMediaPlayerPackage(packageName);
            updateCurrentMediaState(false);
            updateCurrentMediaState();
        }
        synchronized (mMediaPlayerInfoList) {
            for (Map.Entry<Integer, MediaPlayerInfo> entry : mMediaPlayerInfoList.entrySet()) {
@@ -1669,7 +1669,7 @@ public final class Avrcp {
                    int newAddrID = entry.getKey();
                    if (DEBUG) Log.v(TAG, "Set addressed #" + newAddrID + " " + entry.getValue());
                    updateCurrentController(newAddrID, mCurrBrowsePlayerID);
                    updateCurrentMediaState(false);
                    updateCurrentMediaState();
                    return;
                }
            }
@@ -1750,7 +1750,7 @@ public final class Avrcp {
                    addMediaPlayerPackage(packageName);
                }
            }
            updateCurrentMediaState(false);
            updateCurrentMediaState();
        }
    }

@@ -1774,7 +1774,7 @@ public final class Avrcp {
                addMediaPlayerController(controller);
            }

            updateCurrentMediaState(false);
            updateCurrentMediaState();

            if (mMediaPlayerInfoList.size() > 0) {
                // Set the first one as the Addressed Player
@@ -2053,7 +2053,12 @@ public final class Avrcp {
    /* prepare media list & return the media player list response object */
    private MediaPlayerListRsp prepareMediaPlayerRspObj() {
        synchronized (mMediaPlayerInfoList) {
            int numPlayers = mMediaPlayerInfoList.size();
            // TODO(apanicke): This hack will go away as soon as a developer
            // option to enable or disable player selection is created. Right
            // now this is needed to fix BMW i3 carkits and any other carkits
            // that might try to connect to a player that isnt the current
            // player based on this list
            int numPlayers = 1;

            int[] playerIds = new int[numPlayers];
            byte[] playerTypes = new byte[numPlayers];
@@ -2068,7 +2073,10 @@ public final class Avrcp {
            int players = mMediaPlayerInfoList.containsKey(mCurrAddrPlayerID) ? 1 : 0;
            for (Map.Entry<Integer, MediaPlayerInfo> entry : mMediaPlayerInfoList.entrySet()) {
                int idx = players;
                if (entry.getKey() == mCurrAddrPlayerID) idx = 0;
                if (entry.getKey() == mCurrAddrPlayerID)
                    idx = 0;
                else
                    continue; // TODO(apanicke): Remove, see above note
                MediaPlayerInfo info = entry.getValue();
                playerIds[idx] = entry.getKey();
                playerTypes[idx] = info.getMajorType();
@@ -2155,7 +2163,7 @@ public final class Avrcp {
                }
            }
        }
        updateCurrentMediaState(false);
        updateCurrentMediaState();
        return registerRsp;
    }

@@ -2583,6 +2591,7 @@ public final class Avrcp {
        if (!KeyEvent.isMediaKey(code)) {
            Log.w(TAG, "Passthrough non-media key " + op + " (code " + code + ") state " + state);
        }

        mMediaSessionManager.dispatchMediaKeyEvent(event);
        addKeyPending(event);
    }
+2 −1
Original line number Diff line number Diff line
@@ -269,7 +269,8 @@ class BrowsedMediaPlayer {
    /* initialize mediacontroller in order to communicate with media player. */
    private void onBrowseConnect(String connectedPackage, MediaBrowser browser) {
        if (!connectedPackage.equals(mConnectingPackageName)) {
            Log.w(TAG, "onBrowseConnect: recieved callback for package we aren't connecting to "
            Log.w(TAG,
                    "onBrowseConnect: recieved callback for package we aren't connecting to "
                            + connectedPackage);
            return;
        }