AVRCP: Fix NowPlayingList looping

When a controller requested GetFolderItems, we would sometimes send a
NowPlayingListChanged before responding to GetFolderItems, prompting a
new GetFolderItems request.  This put us in an infinite loop.

Test: connect to BMW and note it actually works
Bug: 62775732

Change-Id: Idc669a03f71ed9ec6b211bb5c33fc98548cc9f85
(cherry picked from commit d65422f9b47bff59b12162fc51032eb633f0722f)
diff --git a/src/com/android/bluetooth/avrcp/AddressedMediaPlayer.java b/src/com/android/bluetooth/avrcp/AddressedMediaPlayer.java
index 28a901a..8c94027 100644
--- a/src/com/android/bluetooth/avrcp/AddressedMediaPlayer.java
+++ b/src/com/android/bluetooth/avrcp/AddressedMediaPlayer.java
@@ -54,12 +54,14 @@
     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() {
@@ -67,12 +69,12 @@
         mNowPlayingList = mEmptyNowPlayingList;
         mMediaInterface = null;
         mLastTrackIdSent = MediaSession.QueueItem.UNKNOWN_ID;
+        mNowPlayingListUpdated = false;
     }
 
     /* get now playing list from addressed player */
     void getFolderItemsNowPlaying(byte[] bdaddr, AvrcpCmd.FolderItemsCmd reqObj,
             @Nullable MediaController mediaController) {
-        if (DEBUG) Log.v(TAG, "getFolderItemsNowPlaying");
         if (mediaController == null) {
             // No players (if a player exists, we would have selected it)
             Log.e(TAG, "mediaController = null, sending no available players response");
@@ -120,7 +122,10 @@
             @Nullable MediaController mediaController) {
         if (mediaController == null) return mEmptyNowPlayingList;
         List<MediaSession.QueueItem> items = mediaController.getQueue();
-        if (items == mNowPlayingList) return mNowPlayingList;
+        if (items != null && !mNowPlayingListUpdated) {
+            mNowPlayingList = items;
+            return mNowPlayingList;
+        }
         if (items == null) {
             Log.i(TAG, "null queue from " + mediaController.getPackageName()
                             + ", constructing single-item list");
@@ -131,12 +136,19 @@
             items = new ArrayList<MediaSession.QueueItem>();
             items.add(current);
         }
+
         mNowPlayingList = items;
-        // TODO (jamuraa): test to see if the single-item queue is the same and don't send
-        if (mMediaInterface != null) {
-            mMediaInterface.nowPlayingChangedRsp(AvrcpConstants.NOTIFICATION_TYPE_CHANGED);
-        }
-        return 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
@@ -196,6 +208,7 @@
     }
 
     void updateNowPlayingList(@Nullable MediaController mediaController) {
+        mNowPlayingListUpdated = true;
         getNowPlayingList(mediaController);
     }
 
@@ -239,14 +252,13 @@
     }
 
     void sendTrackChangeWithId(int type, @Nullable MediaController mediaController) {
-        if (DEBUG)
-            Log.d(TAG, "sendTrackChangeWithId (" + type + "): controller " + mediaController);
+        Log.d(TAG, "sendTrackChangeWithId (" + type + "): controller " + mediaController);
         long qid = getActiveQueueItemId(mediaController);
         byte[] track = ByteBuffer.allocate(AvrcpConstants.UID_SIZE).putLong(qid).array();
+        // The nowPlayingList changed: the new list has the full data for the current item
+        if (type == AvrcpConstants.NOTIFICATION_TYPE_CHANGED) sendNowPlayingListChanged();
         mMediaInterface.trackChangedRsp(type, track);
         mLastTrackIdSent = qid;
-        // The nowPlaying might have changed.
-        updateNowPlayingList(mediaController);
     }
 
     /*
diff --git a/src/com/android/bluetooth/avrcp/Avrcp.java b/src/com/android/bluetooth/avrcp/Avrcp.java
index 577aecb..712b2a8 100644
--- a/src/com/android/bluetooth/avrcp/Avrcp.java
+++ b/src/com/android/bluetooth/avrcp/Avrcp.java
@@ -2496,7 +2496,7 @@
             }
         }
 
-        public void uidsChangedRsp(byte[] address, int type, int uidCounter) {
+        public void uidsChangedRsp(int type) {
             if (!registerNotificationRspUIDsChangedNative(type, sUIDCounter)) {
                 Log.e(TAG, "registerNotificationRspUIDsChangedNative failed!");
             }
diff --git a/src/com/android/bluetooth/avrcp/AvrcpMediaRspInterface.java b/src/com/android/bluetooth/avrcp/AvrcpMediaRspInterface.java
index 71493b6..1c7b87c 100644
--- a/src/com/android/bluetooth/avrcp/AvrcpMediaRspInterface.java
+++ b/src/com/android/bluetooth/avrcp/AvrcpMediaRspInterface.java
@@ -45,7 +45,7 @@
 
     public void avalPlayerChangedRsp(byte[] address, int type);
 
-    public void uidsChangedRsp(byte[] address, int type, int uidCounter);
+    public void uidsChangedRsp(int type);
 
     public void nowPlayingChangedRsp(int type);