packages/apps/Bluetooth
修订版 | 3e25adee90d4594ff622bf5f5174333556b7c136 (tree) |
---|---|
时间 | 2017-06-24 10:25:10 |
作者 | Ajay Panicker <apanicke@goog...> |
Commiter | android-build-team Robot |
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)
@@ -54,12 +54,14 @@ public class AddressedMediaPlayer { | ||
54 | 54 | private final List<MediaSession.QueueItem> mEmptyNowPlayingList; |
55 | 55 | |
56 | 56 | private long mLastTrackIdSent; |
57 | + private boolean mNowPlayingListUpdated; | |
57 | 58 | |
58 | 59 | public AddressedMediaPlayer(AvrcpMediaRspInterface mediaInterface) { |
59 | 60 | mEmptyNowPlayingList = new ArrayList<MediaSession.QueueItem>(); |
60 | 61 | mNowPlayingList = mEmptyNowPlayingList; |
61 | 62 | mMediaInterface = mediaInterface; |
62 | 63 | mLastTrackIdSent = MediaSession.QueueItem.UNKNOWN_ID; |
64 | + mNowPlayingListUpdated = false; | |
63 | 65 | } |
64 | 66 | |
65 | 67 | void cleanup() { |
@@ -67,12 +69,12 @@ public class AddressedMediaPlayer { | ||
67 | 69 | mNowPlayingList = mEmptyNowPlayingList; |
68 | 70 | mMediaInterface = null; |
69 | 71 | mLastTrackIdSent = MediaSession.QueueItem.UNKNOWN_ID; |
72 | + mNowPlayingListUpdated = false; | |
70 | 73 | } |
71 | 74 | |
72 | 75 | /* get now playing list from addressed player */ |
73 | 76 | void getFolderItemsNowPlaying(byte[] bdaddr, AvrcpCmd.FolderItemsCmd reqObj, |
74 | 77 | @Nullable MediaController mediaController) { |
75 | - if (DEBUG) Log.v(TAG, "getFolderItemsNowPlaying"); | |
76 | 78 | if (mediaController == null) { |
77 | 79 | // No players (if a player exists, we would have selected it) |
78 | 80 | Log.e(TAG, "mediaController = null, sending no available players response"); |
@@ -120,7 +122,10 @@ public class AddressedMediaPlayer { | ||
120 | 122 | @Nullable MediaController mediaController) { |
121 | 123 | if (mediaController == null) return mEmptyNowPlayingList; |
122 | 124 | List<MediaSession.QueueItem> items = mediaController.getQueue(); |
123 | - if (items == mNowPlayingList) return mNowPlayingList; | |
125 | + if (items != null && !mNowPlayingListUpdated) { | |
126 | + mNowPlayingList = items; | |
127 | + return mNowPlayingList; | |
128 | + } | |
124 | 129 | if (items == null) { |
125 | 130 | Log.i(TAG, "null queue from " + mediaController.getPackageName() |
126 | 131 | + ", constructing single-item list"); |
@@ -131,12 +136,19 @@ public class AddressedMediaPlayer { | ||
131 | 136 | items = new ArrayList<MediaSession.QueueItem>(); |
132 | 137 | items.add(current); |
133 | 138 | } |
139 | + | |
134 | 140 | mNowPlayingList = items; |
135 | - // TODO (jamuraa): test to see if the single-item queue is the same and don't send | |
136 | - if (mMediaInterface != null) { | |
137 | - mMediaInterface.nowPlayingChangedRsp(AvrcpConstants.NOTIFICATION_TYPE_CHANGED); | |
138 | - } | |
139 | - return items; | |
141 | + | |
142 | + if (mNowPlayingListUpdated) sendNowPlayingListChanged(); | |
143 | + | |
144 | + return mNowPlayingList; | |
145 | + } | |
146 | + | |
147 | + private void sendNowPlayingListChanged() { | |
148 | + if (mMediaInterface == null) return; | |
149 | + mMediaInterface.uidsChangedRsp(AvrcpConstants.NOTIFICATION_TYPE_CHANGED); | |
150 | + mMediaInterface.nowPlayingChangedRsp(AvrcpConstants.NOTIFICATION_TYPE_CHANGED); | |
151 | + mNowPlayingListUpdated = false; | |
140 | 152 | } |
141 | 153 | |
142 | 154 | /* Constructs a queue item representing the current playing metadata from an |
@@ -196,6 +208,7 @@ public class AddressedMediaPlayer { | ||
196 | 208 | } |
197 | 209 | |
198 | 210 | void updateNowPlayingList(@Nullable MediaController mediaController) { |
211 | + mNowPlayingListUpdated = true; | |
199 | 212 | getNowPlayingList(mediaController); |
200 | 213 | } |
201 | 214 |
@@ -239,14 +252,13 @@ public class AddressedMediaPlayer { | ||
239 | 252 | } |
240 | 253 | |
241 | 254 | void sendTrackChangeWithId(int type, @Nullable MediaController mediaController) { |
242 | - if (DEBUG) | |
243 | - Log.d(TAG, "sendTrackChangeWithId (" + type + "): controller " + mediaController); | |
255 | + Log.d(TAG, "sendTrackChangeWithId (" + type + "): controller " + mediaController); | |
244 | 256 | long qid = getActiveQueueItemId(mediaController); |
245 | 257 | byte[] track = ByteBuffer.allocate(AvrcpConstants.UID_SIZE).putLong(qid).array(); |
258 | + // The nowPlayingList changed: the new list has the full data for the current item | |
259 | + if (type == AvrcpConstants.NOTIFICATION_TYPE_CHANGED) sendNowPlayingListChanged(); | |
246 | 260 | mMediaInterface.trackChangedRsp(type, track); |
247 | 261 | mLastTrackIdSent = qid; |
248 | - // The nowPlaying might have changed. | |
249 | - updateNowPlayingList(mediaController); | |
250 | 262 | } |
251 | 263 | |
252 | 264 | /* |
@@ -2496,7 +2496,7 @@ public final class Avrcp { | ||
2496 | 2496 | } |
2497 | 2497 | } |
2498 | 2498 | |
2499 | - public void uidsChangedRsp(byte[] address, int type, int uidCounter) { | |
2499 | + public void uidsChangedRsp(int type) { | |
2500 | 2500 | if (!registerNotificationRspUIDsChangedNative(type, sUIDCounter)) { |
2501 | 2501 | Log.e(TAG, "registerNotificationRspUIDsChangedNative failed!"); |
2502 | 2502 | } |
@@ -45,7 +45,7 @@ public interface AvrcpMediaRspInterface { | ||
45 | 45 | |
46 | 46 | public void avalPlayerChangedRsp(byte[] address, int type); |
47 | 47 | |
48 | - public void uidsChangedRsp(byte[] address, int type, int uidCounter); | |
48 | + public void uidsChangedRsp(int type); | |
49 | 49 | |
50 | 50 | public void nowPlayingChangedRsp(int type); |
51 | 51 |